From 5cc5a5a6305c5e31c98590f92ea3ffbff1340abe Mon Sep 17 00:00:00 2001 From: Egil Hansen Date: Wed, 15 Jun 2022 16:35:53 +0000 Subject: [PATCH 01/42] chore: remove support for .netstandard2.1 and net5.0 --- version.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version.json b/version.json index 6bad75a5d..3f126705a 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { - "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json", - "version": "1.30-preview", + "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", + "version": "2.0-alpha", "assemblyVersion": { "precision": "revision" }, @@ -17,9 +17,9 @@ }, "release": { "branchName": "release/v{version}", - "firstUnstableTag": "preview" + "firstUnstableTag": "alpha" }, "pathFilters": [ "./src" ] -} \ No newline at end of file +} From a03cccc7159ad66c96b9b1b7884d093edad3ab0b Mon Sep 17 00:00:00 2001 From: Steven Giesel Date: Sat, 2 Mar 2024 21:59:05 +0100 Subject: [PATCH 02/42] refactor: Remove old frameworks --- .editorconfig | 1 + .github/workflows/ci.yml | 8 -- .github/workflows/docs-deploy.yml | 4 - .github/workflows/release.yml | 4 - Directory.Build.props | 6 +- .../bunit.benchmarks.assets.csproj | 2 +- .../bunit.benchmarks/bunit.benchmarks.csproj | 2 +- bunit.sln | 1 - docs/samples/tests/Directory.Build.props | 2 +- .../tests/razor/TemplateParams1Test.razor | 16 --- .../tests/razor/TemplateParams2Test.razor | 16 --- .../xunit/ComponentFactoryExampleTest.cs | 6 +- .../xunit/CounterWithFancyParagraphTest.cs | 2 - .../tests/xunit/DisposeComponentsTest.cs | 2 - .../tests/xunit/FooBarComponentFactory.cs | 2 - .../ConditionalComponentFactory.cs | 2 - ...actory{TComponent,TSubstituteComponent}.cs | 2 - .../InstanceComponentFactory{TComponent}.cs | 2 - .../TypeBasedComponentFactory{TComponent}.cs | 2 - src/bunit.core/ComponentFactoryCollection.cs | 2 - .../ComponentParameterCollection.cs | 3 +- .../ComponentParameterCollectionBuilder.cs | 35 +---- .../ComponentFactoryCollectionExtensions.cs | 26 ++-- .../RenderedComponentRenderExtensions.cs | 15 +- .../RenderedFragmentInvokeAsyncExtensions.cs | 12 +- .../TestContextBaseRenderExtensions.cs | 6 +- src/bunit.core/IComponentFactory.cs | 5 - .../Rendering/BunitComponentActivator.cs | 5 +- src/bunit.core/Rendering/RenderEvent.cs | 3 +- src/bunit.core/Rendering/TestRenderer.cs | 74 ++-------- src/bunit.core/StringSyntaxAttribute.cs | 26 ---- .../MemberNotNullAttribute.cs | 29 ---- src/bunit.core/TestContextBase.cs | 4 - .../FakePersistentComponentState.cs | 11 +- .../FakePersistentComponentStateStore.cs | 7 - .../TestContextBaseExtensions.cs | 8 +- src/bunit.core/TestServiceProvider.cs | 23 +-- src/bunit.core/bunit.core.csproj | 26 +--- .../ComponentStubAttribute.cs | 2 - src/bunit.web.query/bunit.web.query.csproj | 30 +--- .../Asserting/CompareToExtensions.cs | 30 ++-- .../Asserting/DiffAssertExtensions.cs | 9 +- .../FocusAsyncAssertJSInteropExtensions.cs | 4 - ...ocusOnNavigateAssertJSInteropExtensions.cs | 3 - .../JSInvokeCountExpectedException.cs | 8 +- .../Asserting/JSRuntimeAssertExtensions.cs | 6 +- .../MarkupMatchesAssertExtensions.cs | 126 ++++++----------- .../ShouldBeAdditionAssertExtensions.cs | 15 +- .../ShouldBeRemovalAssertExtensions.cs | 15 +- .../ShouldBeTextChangeAssertExtensions.cs | 24 ++-- .../StubComponentFactory.cs | 2 - src/bunit.web/Diffing/DiffMarkupFormatter.cs | 3 +- .../DetailsElementEventDispatchExtensions.cs | 4 - .../DialogEventDispatchExtensions.cs | 2 - .../MouseEventDispatchExtensions.cs | 133 ------------------ .../TriggerEventDispatchExtensions.cs | 11 +- .../Extensions/ElementNotFoundException.cs | 5 +- .../Extensions/InputFile/BUnitBrowserFile.cs | 4 +- .../Extensions/InputFile/InputFileContent.cs | 8 +- .../InputFile/InputFileExtensions.cs | 12 +- .../Extensions/NodePrintExtensions.cs | 18 +-- .../Extensions/RenderedFragmentExtensions.cs | 12 +- ...tubComponentFactoryCollectionExtensions.cs | 20 +-- .../Extensions/TestRendererExtensions.cs | 9 +- .../TestServiceProviderExtensions.cs | 13 +- .../WaitForHelpers/WaitForElementsHelper.cs | 3 +- src/bunit.web/JSInterop/BunitJSInterop.cs | 27 +--- .../BunitJSInteropSetupExtensions.cs | 20 +-- .../BunitJSInteropSetupExtensions.net5.cs | 17 +-- .../JSInterop/BunitJSModuleInterop.cs | 2 - .../Implementation/BunitJSObjectReference.cs | 7 - .../Implementation/BunitJSRuntime.net5.cs | 4 +- .../Implementation/JSRuntimeExtensions.cs | 14 -- .../FocusAsyncInvocationHandler.cs | 6 - .../Implementation/FocusOnNavigateHandler.cs | 4 - .../InputFileInvocationHandler.cs | 4 +- .../JSObjectReferenceInvocationHandler.cs | 3 - ...eModeJSObjectReferenceInvocationHandler.cs | 3 - ...isableNavigationPromptInvocationHandler.cs | 2 - ...EnableNavigationPromptInvocationHandler.cs | 2 - .../VirtualizeJSRuntimeInvocationHandler.cs | 10 -- .../JSRuntimeInvocationHandler.cs | 4 - .../JSInterop/JSRuntimeInvocation.cs | 4 - .../JSRuntimeUnhandledInvocationException.cs | 6 - src/bunit.web/Rendering/BunitHtmlParser.cs | 7 +- src/bunit.web/Rendering/Internal/Htmlizer.cs | 5 +- src/bunit.web/Rendering/WebTestRenderer.cs | 13 +- src/bunit.web/TestContext.cs | 6 +- .../FakeAuthorizationExtensions.cs | 3 +- .../Authorization/FakeAuthorizationService.cs | 3 +- .../CapturedParameterView{TComponent}.cs | 5 +- .../ComponentDoubleBase{TComponent}.cs | 2 - .../Components/ParameterNotFoundException.cs | 4 +- .../Components/Stub{TComponent}.cs | 2 - .../ErrorBoundary/BunitErrorBoundaryLogger.cs | 2 - .../MissingMockStringLocalizationException.cs | 8 +- .../FakeNavigationManager.cs | 48 ------- .../NavigationManager/NavigationHistory.cs | 65 +-------- .../NavigationManager/NavigationOptions.cs | 32 ----- .../NavigationManager/NavigationState.cs | 2 - .../BunitScrollToLocationHash.cs | 2 - src/bunit.web/bunit.web.csproj | 44 +----- src/bunit/bunit.csproj | 2 +- .../ConditionalComponentFactoryTest.cs | 3 - .../GenericComponentFactoryTest.cs | 10 -- .../InstanceComponentFactoryTest.cs | 3 - .../TypeBasedComponentFactoryTest.cs | 6 +- ...omponentParameterCollectionBuilderTests.cs | 5 - .../Rendering/BunitComponentActivatorTest.cs | 4 - .../Rendering/TestRendererTest.cs | 44 +++--- .../Rendering/TestRendererTest.net5.cs | 10 -- .../TestContextBaseTest.net5.cs | 4 - .../FakePersistentComponentStateTest.cs | 10 -- .../TestServiceProviderTest.cs | 4 - .../bunit.core.tests/bunit.core.tests.csproj | 2 +- .../TaskAssertionExtensions.cs | 9 -- .../InteractiveAutoComponent.razor | 10 +- .../InteractiveServerComponent.razor | 10 +- .../InteractiveWebAssemblyComponent.razor | 10 +- .../PersistentComponentStateSample.razor.cs | 2 - .../SampleComponents/TriggerTester.cs | 3 +- .../Serilog.Sinks.XUnit/TestOutputSink.cs | 3 +- .../XUnitLoggerConfigurationExtensions.cs | 24 ++-- .../bunit.testassets/bunit.testassets.csproj | 29 +--- .../bunit.web.query.tests.csproj | 2 +- .../MarkupMatchesAssertExtensionsTest.net5.cs | 6 - .../StubComponentFactoryTest.cs | 5 +- ...ilsElementEventDispatcherExtensionsTest.cs | 3 - .../EventDispatchExtensionsTest.cs | 12 +- .../GeneralEventDispatchExtensionsTest.cs | 7 +- .../InputEventDispatchExtensionsTest.cs | 9 -- .../TriggerEventSpy.cs | 9 +- .../Extensions/InputFile/InputFileTests.cs | 4 +- .../JSInterop/BunitJSInteropTest.net5.cs | 9 +- .../JSInterop/BunitJSObjectReferenceTest.cs | 26 ++-- .../FocusAsyncInvocationHandlerTest.cs | 8 -- .../FocusOnNavigateHandlerTest.cs | 13 -- ...irtualizeJSRuntimeInvocationHandlerTest.cs | 11 +- .../JSInterop/JSRuntimeInvocationTest.cs | 6 +- ...RuntimeUnhandledInvocationExceptionTest.cs | 4 - ...meUnhandledInvocationExceptionTest.net5.cs | 8 -- .../Rendering/Internal/HtmlizerTests.net5.cs | 5 - tests/bunit.web.tests/TestContextTest.net6.cs | 8 -- .../TestAuthorizationContextTest.cs | 4 +- .../Components/CapturedParameterViewTest.cs | 2 - .../Components/ComponentDoubleBaseTest.cs | 2 - .../TestDoubles/Components/StubTest.cs | 2 - .../FakeNavigationManagerTest.cs | 41 +----- .../TestUtilities/MockingHelpers.cs | 6 +- tests/bunit.web.tests/bunit.web.tests.csproj | 2 +- 150 files changed, 269 insertions(+), 1477 deletions(-) delete mode 100644 docs/samples/tests/razor/TemplateParams1Test.razor delete mode 100644 docs/samples/tests/razor/TemplateParams2Test.razor delete mode 100644 src/bunit.core/StringSyntaxAttribute.cs delete mode 100644 src/bunit.core/System.Diagnostics.CodeAnalysis/MemberNotNullAttribute.cs delete mode 100644 src/bunit.web/TestDoubles/NavigationManager/NavigationOptions.cs diff --git a/.editorconfig b/.editorconfig index 1ee6999e5..5472a756f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -490,6 +490,7 @@ dotnet_diagnostic.CA1062.severity = none # CA1062: Validate arguments of public dotnet_diagnostic.CA1707.severity = none # CA1707: Identifiers should not contain underscores dotnet_diagnostic.CA1812.severity = none # CA1812: Avoid uninstantiated internal classes - components under test are never instantiated directly. dotnet_diagnostic.CA1822.severity = suggestion # CA1822: Mark members as static +dotnet_diagnostic.CA1859.severity = none # CA1859: Change return type of method dotnet_diagnostic.CA2007.severity = none # CA2007: Consider calling ConfigureAwait on the awaited task # Microsoft - FxCop diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 06d6fb08b..fbaf0c949 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -129,10 +129,6 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: | - 3.1.x - 5.0.x - 6.0.x - 7.0.x 8.0.x 9.0.x @@ -207,10 +203,6 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: | - 3.1.x - 5.0.x - 6.0.x - 7.0.x 8.0.x 9.0.x diff --git a/.github/workflows/docs-deploy.yml b/.github/workflows/docs-deploy.yml index e8ebf51f1..5460c6a55 100644 --- a/.github/workflows/docs-deploy.yml +++ b/.github/workflows/docs-deploy.yml @@ -72,10 +72,6 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: | - 3.1.x - 5.0.x - 6.0.x - 7.0.x 8.0.x 9.0.x diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9172732d0..2738b7e35 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -57,10 +57,6 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: | - 3.1.x - 5.0.x - 6.0.x - 7.0.x 8.0.x 9.0.x diff --git a/Directory.Build.props b/Directory.Build.props index 765ddd563..ecbd7c3b8 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,10 +2,6 @@ - 3.1.* - 5.0.* - 6.0.* - 7.0.* 8.0.* 9.0.0-* @@ -40,7 +36,7 @@ AllEnabledByDefault true - 7 + 8 true diff --git a/benchmark/bunit.benchmarks.assets/bunit.benchmarks.assets.csproj b/benchmark/bunit.benchmarks.assets/bunit.benchmarks.assets.csproj index 358670ae2..d847c3ba1 100644 --- a/benchmark/bunit.benchmarks.assets/bunit.benchmarks.assets.csproj +++ b/benchmark/bunit.benchmarks.assets/bunit.benchmarks.assets.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 enable enable diff --git a/benchmark/bunit.benchmarks/bunit.benchmarks.csproj b/benchmark/bunit.benchmarks/bunit.benchmarks.csproj index ffeb33523..1212e538f 100644 --- a/benchmark/bunit.benchmarks/bunit.benchmarks.csproj +++ b/benchmark/bunit.benchmarks/bunit.benchmarks.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net8.0 enable false diff --git a/bunit.sln b/bunit.sln index 4ce0606e1..c39a1c1ba 100644 --- a/bunit.sln +++ b/bunit.sln @@ -52,7 +52,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".workflows", ".workflows", .github\workflows\ci.yml = .github\workflows\ci.yml .github\workflows\docs-deploy.yml = .github\workflows\docs-deploy.yml .github\workflows\prepare-release.yml = .github\workflows\prepare-release.yml - .github\workflows\release-preview.yml = .github\workflows\release-preview.yml .github\workflows\release.yml = .github\workflows\release.yml EndProjectSection EndProject diff --git a/docs/samples/tests/Directory.Build.props b/docs/samples/tests/Directory.Build.props index 8422a0457..8b4e7a76d 100644 --- a/docs/samples/tests/Directory.Build.props +++ b/docs/samples/tests/Directory.Build.props @@ -1,6 +1,6 @@ - netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0 + net8.0;net9.0 false true false diff --git a/docs/samples/tests/razor/TemplateParams1Test.razor b/docs/samples/tests/razor/TemplateParams1Test.razor deleted file mode 100644 index 612a27abb..000000000 --- a/docs/samples/tests/razor/TemplateParams1Test.razor +++ /dev/null @@ -1,16 +0,0 @@ -@inherits TestContext - -@code -{ -#if NET6_0 - [Fact] - public void Test() - { - var cut = Render(@ - - ); - } -#endif -} \ No newline at end of file diff --git a/docs/samples/tests/razor/TemplateParams2Test.razor b/docs/samples/tests/razor/TemplateParams2Test.razor deleted file mode 100644 index 3afcffd59..000000000 --- a/docs/samples/tests/razor/TemplateParams2Test.razor +++ /dev/null @@ -1,16 +0,0 @@ -@inherits TestContext - -@code -{ -#if NET6_0 - [Fact] - public void Test() - { - var cut = Render(@ - - ); - } -#endif -} \ No newline at end of file diff --git a/docs/samples/tests/xunit/ComponentFactoryExampleTest.cs b/docs/samples/tests/xunit/ComponentFactoryExampleTest.cs index 580ab4096..f11a8c898 100644 --- a/docs/samples/tests/xunit/ComponentFactoryExampleTest.cs +++ b/docs/samples/tests/xunit/ComponentFactoryExampleTest.cs @@ -1,5 +1,3 @@ -#if NET5_0_OR_GREATER - using Microsoft.AspNetCore.Components.Web; using Xunit; using Bunit; @@ -24,6 +22,4 @@ public void ReplacesFooWithBarDuringTest() Assert.Equal(1, cut.FindComponents().Count); } } -} - -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/docs/samples/tests/xunit/CounterWithFancyParagraphTest.cs b/docs/samples/tests/xunit/CounterWithFancyParagraphTest.cs index 94ab7a42d..565efcbfc 100644 --- a/docs/samples/tests/xunit/CounterWithFancyParagraphTest.cs +++ b/docs/samples/tests/xunit/CounterWithFancyParagraphTest.cs @@ -1,4 +1,3 @@ -#if NET5_0_OR_GREATER using Xunit; using Bunit; using Moq; @@ -38,4 +37,3 @@ public void CounterShouldIncrementWhenClicked_NSubstitute() } } } -#endif \ No newline at end of file diff --git a/docs/samples/tests/xunit/DisposeComponentsTest.cs b/docs/samples/tests/xunit/DisposeComponentsTest.cs index 5e0c403b1..5b95b0317 100644 --- a/docs/samples/tests/xunit/DisposeComponentsTest.cs +++ b/docs/samples/tests/xunit/DisposeComponentsTest.cs @@ -32,7 +32,6 @@ public void ShouldCatchExceptionInDispose() Assert.Throws(act); } -#if NET5_0_OR_GREATER [Fact] public void ShouldCatchExceptionInDisposeAsync() { @@ -42,5 +41,4 @@ public void ShouldCatchExceptionInDisposeAsync() var exception = Renderer.UnhandledException.Result; Assert.IsType(exception); } -#endif } \ No newline at end of file diff --git a/docs/samples/tests/xunit/FooBarComponentFactory.cs b/docs/samples/tests/xunit/FooBarComponentFactory.cs index da18b552c..aa5cd9ce4 100644 --- a/docs/samples/tests/xunit/FooBarComponentFactory.cs +++ b/docs/samples/tests/xunit/FooBarComponentFactory.cs @@ -1,4 +1,3 @@ -#if NET5_0_OR_GREATER namespace Bunit.Docs.Samples { using System; @@ -14,4 +13,3 @@ public IComponent Create(Type componentType) => new Bar(); } } -#endif \ No newline at end of file diff --git a/src/bunit.core/ComponentFactories/ConditionalComponentFactory.cs b/src/bunit.core/ComponentFactories/ConditionalComponentFactory.cs index d490d0258..0248ea7be 100644 --- a/src/bunit.core/ComponentFactories/ConditionalComponentFactory.cs +++ b/src/bunit.core/ComponentFactories/ConditionalComponentFactory.cs @@ -1,4 +1,3 @@ -#if NET5_0_OR_GREATER namespace Bunit.ComponentFactories; internal sealed class ConditionalComponentFactory : IComponentFactory @@ -18,4 +17,3 @@ public bool CanCreate(Type componentType) public IComponent Create(Type componentType) => factory(componentType); } -#endif diff --git a/src/bunit.core/ComponentFactories/GenericComponentFactory{TComponent,TSubstituteComponent}.cs b/src/bunit.core/ComponentFactories/GenericComponentFactory{TComponent,TSubstituteComponent}.cs index dacf64c66..17dc53538 100644 --- a/src/bunit.core/ComponentFactories/GenericComponentFactory{TComponent,TSubstituteComponent}.cs +++ b/src/bunit.core/ComponentFactories/GenericComponentFactory{TComponent,TSubstituteComponent}.cs @@ -1,4 +1,3 @@ -#if NET5_0_OR_GREATER namespace Bunit.ComponentFactories; internal sealed class GenericComponentFactory : IComponentFactory @@ -9,4 +8,3 @@ internal sealed class GenericComponentFactory public IComponent Create(Type componentType) => Activator.CreateInstance()!; } -#endif diff --git a/src/bunit.core/ComponentFactories/InstanceComponentFactory{TComponent}.cs b/src/bunit.core/ComponentFactories/InstanceComponentFactory{TComponent}.cs index e1126d435..0ce047387 100644 --- a/src/bunit.core/ComponentFactories/InstanceComponentFactory{TComponent}.cs +++ b/src/bunit.core/ComponentFactories/InstanceComponentFactory{TComponent}.cs @@ -1,4 +1,3 @@ -#if NET5_0_OR_GREATER namespace Bunit.ComponentFactories; internal sealed class InstanceComponentFactory : IComponentFactory @@ -28,4 +27,3 @@ public IComponent Create(Type componentType) return instance; } } -#endif diff --git a/src/bunit.core/ComponentFactories/TypeBasedComponentFactory{TComponent}.cs b/src/bunit.core/ComponentFactories/TypeBasedComponentFactory{TComponent}.cs index 1d9678e73..9beb58c07 100644 --- a/src/bunit.core/ComponentFactories/TypeBasedComponentFactory{TComponent}.cs +++ b/src/bunit.core/ComponentFactories/TypeBasedComponentFactory{TComponent}.cs @@ -1,4 +1,3 @@ -#if NET5_0_OR_GREATER namespace Bunit.ComponentFactories; internal sealed class TypeBasedComponentFactory : IComponentFactory @@ -15,4 +14,3 @@ public bool CanCreate(Type componentType) public IComponent Create(Type componentType) => componentFactory.Invoke(); } -#endif diff --git a/src/bunit.core/ComponentFactoryCollection.cs b/src/bunit.core/ComponentFactoryCollection.cs index 9a156fdbc..9dd788300 100644 --- a/src/bunit.core/ComponentFactoryCollection.cs +++ b/src/bunit.core/ComponentFactoryCollection.cs @@ -1,4 +1,3 @@ -#if NET5_0_OR_GREATER using System.Collections; namespace Bunit; @@ -91,4 +90,3 @@ public sealed class ComponentFactoryCollection : IList /// An object that can be used to iterate through the . IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)factories).GetEnumerator(); } -#endif diff --git a/src/bunit.core/ComponentParameterCollection.cs b/src/bunit.core/ComponentParameterCollection.cs index 7b248b096..f8052c5c0 100644 --- a/src/bunit.core/ComponentParameterCollection.cs +++ b/src/bunit.core/ComponentParameterCollection.cs @@ -40,8 +40,7 @@ public void Add(ComponentParameter item) /// Parameters to add. public void Add(IEnumerable parameters) { - if (parameters is null) - throw new ArgumentNullException(nameof(parameters)); + ArgumentNullException.ThrowIfNull(parameters); foreach (var cp in parameters) { diff --git a/src/bunit.core/ComponentParameterCollectionBuilder.cs b/src/bunit.core/ComponentParameterCollectionBuilder.cs index f4c1fa04e..7dbb0f690 100644 --- a/src/bunit.core/ComponentParameterCollectionBuilder.cs +++ b/src/bunit.core/ComponentParameterCollectionBuilder.cs @@ -50,11 +50,8 @@ public ComponentParameterCollectionBuilder(ActionThis . public ComponentParameterCollectionBuilder Add(Expression> parameterSelector, [AllowNull] TValue value) { -#if !NET8_0_OR_GREATER - var (name, cascadingValueName, isCascading) = GetParameterInfo(parameterSelector); -#else var (name, cascadingValueName, isCascading) = GetParameterInfo(parameterSelector, value); -#endif + return isCascading ? AddCascadingValueParameter(cascadingValueName, value) : AddParameter(name, value); @@ -91,8 +88,7 @@ public ComponentParameterCollectionBuilder Add(ExpressionThis . public ComponentParameterCollectionBuilder Add(Expression?>> parameterSelector, Func markupFactory) { - if (markupFactory is null) - throw new ArgumentNullException(nameof(markupFactory)); + ArgumentNullException.ThrowIfNull(markupFactory); return Add(parameterSelector, v => b => b.AddMarkupContent(0, markupFactory(v))); } @@ -109,8 +105,7 @@ public ComponentParameterCollectionBuilder Add(Expression Add(Expression?>> parameterSelector, Func>> templateFactory) where TChildComponent : IComponent { - if (templateFactory is null) - throw new ArgumentNullException(nameof(templateFactory)); + ArgumentNullException.ThrowIfNull(templateFactory); return Add(parameterSelector, value => GetRenderFragment(templateFactory(value))); } @@ -344,17 +339,12 @@ public ComponentParameterCollectionBuilder Bind( Action changedAction, Expression>? valueExpression = null) { - #if !NET8_0_OR_GREATER - var (parameterName, _, isCascading) = GetParameterInfo(parameterSelector); - #else var (parameterName, _, isCascading) = GetParameterInfo(parameterSelector, initialValue); - #endif if (isCascading) throw new ArgumentException("Using Bind with a cascading parameter is not allowed.", parameterName); - if (changedAction is null) - throw new ArgumentNullException(nameof(changedAction)); + ArgumentNullException.ThrowIfNull(changedAction); var changedName = $"{parameterName}Changed"; var expressionName = $"{parameterName}Expression"; @@ -437,14 +427,10 @@ public bool TryAdd(string name, [AllowNull] TValue value) public ComponentParameterCollection Build() => parameters; private static (string Name, string? CascadingValueName, bool IsCascading) GetParameterInfo( - Expression> parameterSelector -#if NET8_0_OR_GREATER - , object? value -#endif + Expression> parameterSelector, object? value ) { - if (parameterSelector is null) - throw new ArgumentNullException(nameof(parameterSelector)); + ArgumentNullException.ThrowIfNull(parameterSelector); if (parameterSelector.Body is not MemberExpression { Member: PropertyInfo propInfoCandidate }) throw new ArgumentException($"The parameter selector '{parameterSelector}' does not resolve to a public property on the component '{typeof(TComponent)}'.", nameof(parameterSelector)); @@ -454,14 +440,6 @@ Expression> parameterSelector : propInfoCandidate; var paramAttr = propertyInfo?.GetCustomAttribute(inherit: true); - #if !NET8_0_OR_GREATER - var cascadingParamAttr = propertyInfo?.GetCustomAttribute(inherit: true); - - if (propertyInfo is null || (paramAttr is null && cascadingParamAttr is null)) - throw new ArgumentException($"The parameter selector '{parameterSelector}' does not resolve to a public property on the component '{typeof(TComponent)}' with a [Parameter] or [CascadingParameter] attribute.", nameof(parameterSelector)); - - return (propertyInfo.Name, CascadingValueName: cascadingParamAttr?.Name, IsCascading: cascadingParamAttr is not null); - #else var cascadingParamAttrBase = propertyInfo?.GetCustomAttribute(inherit: true); if (propertyInfo is null || (paramAttr is null && cascadingParamAttrBase is null)) @@ -494,7 +472,6 @@ static ArgumentException CreateErrorMessageForSupplyFromQuery( NavigationManager.NavigateTo(uri); """); } - #endif } private static bool HasChildContentParameter() diff --git a/src/bunit.core/Extensions/ComponentFactoryCollectionExtensions.cs b/src/bunit.core/Extensions/ComponentFactoryCollectionExtensions.cs index ec2025e02..d17d27788 100644 --- a/src/bunit.core/Extensions/ComponentFactoryCollectionExtensions.cs +++ b/src/bunit.core/Extensions/ComponentFactoryCollectionExtensions.cs @@ -1,4 +1,3 @@ -#if NET5_0_OR_GREATER using Bunit.ComponentFactories; namespace Bunit; @@ -21,8 +20,7 @@ public static ComponentFactoryCollection Add(t where TComponent : IComponent where TSubstituteComponent : IComponent { - if (factories is null) - throw new ArgumentNullException(nameof(factories)); + ArgumentNullException.ThrowIfNull(factories); factories.Add(new GenericComponentFactory()); @@ -44,10 +42,8 @@ public static ComponentFactoryCollection Add(t public static ComponentFactoryCollection Add(this ComponentFactoryCollection factories, TComponent instance) where TComponent : IComponent { - if (factories is null) - throw new ArgumentNullException(nameof(factories)); - if (instance is null) - throw new ArgumentNullException(nameof(instance)); + ArgumentNullException.ThrowIfNull(factories); + ArgumentNullException.ThrowIfNull(instance); factories.Add(new InstanceComponentFactory(instance)); @@ -70,10 +66,8 @@ public static ComponentFactoryCollection Add(this ComponentFactoryCo public static ComponentFactoryCollection Add(this ComponentFactoryCollection factories, Func factory) where TComponent : IComponent { - if (factories is null) - throw new ArgumentNullException(nameof(factories)); - if (factory is null) - throw new ArgumentNullException(nameof(factory)); + ArgumentNullException.ThrowIfNull(factories); + ArgumentNullException.ThrowIfNull(factory); factories.Add(new TypeBasedComponentFactory(factory)); @@ -95,16 +89,12 @@ public static ComponentFactoryCollection Add(this ComponentFactoryCo /// Thrown when , , and/or is null. public static ComponentFactoryCollection Add(this ComponentFactoryCollection factories, Predicate condition, Func factory) { - if (factories is null) - throw new ArgumentNullException(nameof(factories)); - if (condition is null) - throw new ArgumentNullException(nameof(condition)); - if (factory is null) - throw new ArgumentNullException(nameof(factory)); + ArgumentNullException.ThrowIfNull(factories); + ArgumentNullException.ThrowIfNull(condition); + ArgumentNullException.ThrowIfNull(factory); factories.Add(new ConditionalComponentFactory(condition, factory)); return factories; } } -#endif diff --git a/src/bunit.core/Extensions/RenderedComponentRenderExtensions.cs b/src/bunit.core/Extensions/RenderedComponentRenderExtensions.cs index 5e01c233b..a6de0a34b 100644 --- a/src/bunit.core/Extensions/RenderedComponentRenderExtensions.cs +++ b/src/bunit.core/Extensions/RenderedComponentRenderExtensions.cs @@ -26,8 +26,7 @@ public static void Render(this IRenderedComponentBase re public static void SetParametersAndRender(this IRenderedComponentBase renderedComponent, ParameterView parameters) where TComponent : IComponent { - if (renderedComponent is null) - throw new ArgumentNullException(nameof(renderedComponent)); + ArgumentNullException.ThrowIfNull(renderedComponent); var renderer = (TestRenderer)renderedComponent.Services.GetRequiredService().Renderer; @@ -50,10 +49,8 @@ public static void SetParametersAndRender(this IRenderedComponentBas public static void SetParametersAndRender(this IRenderedComponentBase renderedComponent, params ComponentParameter[] parameters) where TComponent : IComponent { - if (renderedComponent is null) - throw new ArgumentNullException(nameof(renderedComponent)); - if (parameters is null) - throw new ArgumentNullException(nameof(parameters)); + ArgumentNullException.ThrowIfNull(renderedComponent); + ArgumentNullException.ThrowIfNull(parameters); SetParametersAndRender(renderedComponent, ToParameterView(parameters)); } @@ -67,10 +64,8 @@ public static void SetParametersAndRender(this IRenderedComponentBas public static void SetParametersAndRender(this IRenderedComponentBase renderedComponent, Action> parameterBuilder) where TComponent : IComponent { - if (renderedComponent is null) - throw new ArgumentNullException(nameof(renderedComponent)); - if (parameterBuilder is null) - throw new ArgumentNullException(nameof(parameterBuilder)); + ArgumentNullException.ThrowIfNull(renderedComponent); + ArgumentNullException.ThrowIfNull(parameterBuilder); var builder = new ComponentParameterCollectionBuilder(parameterBuilder); SetParametersAndRender(renderedComponent, ToParameterView(builder.Build())); diff --git a/src/bunit.core/Extensions/RenderedFragmentInvokeAsyncExtensions.cs b/src/bunit.core/Extensions/RenderedFragmentInvokeAsyncExtensions.cs index d9078b673..6f0b6e04c 100644 --- a/src/bunit.core/Extensions/RenderedFragmentInvokeAsyncExtensions.cs +++ b/src/bunit.core/Extensions/RenderedFragmentInvokeAsyncExtensions.cs @@ -15,8 +15,7 @@ public static class RenderedFragmentInvokeAsyncExtensions /// A that will be completed when the action has finished executing or is suspended by an asynchronous operation. public static Task InvokeAsync(this IRenderedFragmentBase renderedFragment, Action workItem) { - if (renderedFragment is null) - throw new ArgumentNullException(nameof(renderedFragment)); + ArgumentNullException.ThrowIfNull(renderedFragment); return renderedFragment .Services @@ -34,8 +33,7 @@ public static Task InvokeAsync(this IRenderedFragmentBase renderedFragment, Acti /// A that will be completed when the action has finished executing. public static Task InvokeAsync(this IRenderedFragmentBase renderedFragment, Func workItem) { - if (renderedFragment is null) - throw new ArgumentNullException(nameof(renderedFragment)); + ArgumentNullException.ThrowIfNull(renderedFragment); return renderedFragment .Services @@ -53,8 +51,7 @@ public static Task InvokeAsync(this IRenderedFragmentBase renderedFragment, Func /// A that will be completed when the action has finished executing, with the return value from . public static Task InvokeAsync(this IRenderedFragmentBase renderedFragment, Func workItem) { - if (renderedFragment is null) - throw new ArgumentNullException(nameof(renderedFragment)); + ArgumentNullException.ThrowIfNull(renderedFragment); return renderedFragment .Services @@ -72,8 +69,7 @@ public static Task InvokeAsync(this IRenderedFragmentBase renderedFragment /// A that will be completed when the action has finished executing, with the return value from . public static Task InvokeAsync(this IRenderedFragmentBase renderedFragment, Func> workItem) { - if (renderedFragment is null) - throw new ArgumentNullException(nameof(renderedFragment)); + ArgumentNullException.ThrowIfNull(renderedFragment); return renderedFragment .Services diff --git a/src/bunit.core/Extensions/TestContextBaseRenderExtensions.cs b/src/bunit.core/Extensions/TestContextBaseRenderExtensions.cs index be5f03782..53c6abd49 100644 --- a/src/bunit.core/Extensions/TestContextBaseRenderExtensions.cs +++ b/src/bunit.core/Extensions/TestContextBaseRenderExtensions.cs @@ -17,8 +17,7 @@ public static class TestContextBaseRenderExtensions public static IRenderedComponentBase RenderInsideRenderTree(this TestContextBase testContext, RenderFragment renderFragment) where TComponent : IComponent { - if (testContext is null) - throw new ArgumentNullException(nameof(testContext)); + ArgumentNullException.ThrowIfNull(testContext); var baseResult = RenderInsideRenderTree(testContext, renderFragment); return testContext.Renderer.FindComponent(baseResult); @@ -32,8 +31,7 @@ public static IRenderedComponentBase RenderInsideRenderTreeA . public static IRenderedFragmentBase RenderInsideRenderTree(this TestContextBase testContext, RenderFragment renderFragment) { - if (testContext is null) - throw new ArgumentNullException(nameof(testContext)); + ArgumentNullException.ThrowIfNull(testContext); // Wrap fragment in a FragmentContainer so the start of the test supplied // razor fragment can be found after, and then wrap in any layout components diff --git a/src/bunit.core/IComponentFactory.cs b/src/bunit.core/IComponentFactory.cs index 50e18fee5..2cb139b87 100644 --- a/src/bunit.core/IComponentFactory.cs +++ b/src/bunit.core/IComponentFactory.cs @@ -1,7 +1,3 @@ -#if NET5_0_OR_GREATER -using System; -using Microsoft.AspNetCore.Components; - namespace Bunit; /// @@ -22,4 +18,3 @@ public interface IComponentFactory /// The type of component to create. IComponent Create(Type componentType); } -#endif diff --git a/src/bunit.core/Rendering/BunitComponentActivator.cs b/src/bunit.core/Rendering/BunitComponentActivator.cs index e7afdd5c8..400d94877 100644 --- a/src/bunit.core/Rendering/BunitComponentActivator.cs +++ b/src/bunit.core/Rendering/BunitComponentActivator.cs @@ -1,5 +1,3 @@ -#if NET5_0_OR_GREATER - namespace Bunit.Rendering; internal class BunitComponentActivator : IComponentActivator @@ -47,9 +45,8 @@ private sealed class DefaultComponentActivator : IComponentActivator /// public IComponent CreateInstance([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type componentType) - { + { return (IComponent)Activator.CreateInstance(componentType)!; } } } -#endif diff --git a/src/bunit.core/Rendering/RenderEvent.cs b/src/bunit.core/Rendering/RenderEvent.cs index 77a823ee0..bbb410653 100644 --- a/src/bunit.core/Rendering/RenderEvent.cs +++ b/src/bunit.core/Rendering/RenderEvent.cs @@ -22,8 +22,7 @@ public sealed class RenderEvent /// A tuple of statuses indicating whether the rendered component rendered during the render cycle, if it changed or if it was disposed. public (bool Rendered, bool Changed, bool Disposed) GetRenderStatus(IRenderedFragmentBase renderedComponent) { - if (renderedComponent is null) - throw new ArgumentNullException(nameof(renderedComponent)); + ArgumentNullException.ThrowIfNull(renderedComponent); return statuses.TryGetValue(renderedComponent.ComponentId, out var status) ? (status.Rendered, status.Changed, status.Disposed) diff --git a/src/bunit.core/Rendering/TestRenderer.cs b/src/bunit.core/Rendering/TestRenderer.cs index bf7449b4e..f78298ffc 100644 --- a/src/bunit.core/Rendering/TestRenderer.cs +++ b/src/bunit.core/Rendering/TestRenderer.cs @@ -10,17 +10,11 @@ namespace Bunit.Rendering; /// public class TestRenderer : Renderer, ITestRenderer { -#if NET8_0_OR_GREATER [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_isBatchInProgress")] extern static ref bool GetIsBatchInProgressField(Renderer renderer); [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "SetDirectParameters")] extern static void CallSetDirectParameters(ComponentState componentState, ParameterView parameters); -#else - private static readonly Type RendererType = typeof(Renderer); - private static readonly MethodInfo GetRequiredComponentStateMethod = RendererType.GetMethod("GetRequiredComponentState", BindingFlags.Instance | BindingFlags.NonPublic)!; - private static readonly FieldInfo IsBatchInProgressField = RendererType.GetField("_isBatchInProgress", BindingFlags.Instance | BindingFlags.NonPublic)!; -#endif private readonly object renderTreeUpdateLock = new(); private readonly Dictionary renderedComponents = new(); @@ -36,20 +30,12 @@ private bool IsBatchInProgress #pragma warning disable S1144 // Unused private types or members should be removed get { -#if NET8_0_OR_GREATER return GetIsBatchInProgressField(this); -#else - return (bool)(IsBatchInProgressField.GetValue(this) ?? false); -#endif } #pragma warning restore S1144 // Unused private types or members should be removed set { -#if NET8_0_OR_GREATER GetIsBatchInProgressField(this) = value; -#else - IsBatchInProgressField.SetValue(this, value); -#endif } } @@ -64,17 +50,6 @@ private bool IsBatchInProgress /// internal int RenderCount { get; private set; } -#if NETSTANDARD - /// - /// Initializes a new instance of the class. - /// - public TestRenderer(IRenderedComponentActivator renderedComponentActivator, TestServiceProvider services, ILoggerFactory loggerFactory) - : base(services, loggerFactory) - { - logger = loggerFactory.CreateLogger(); - this.activator = renderedComponentActivator; - } -#elif NET5_0_OR_GREATER /// /// Initializes a new instance of the class. /// @@ -94,7 +69,6 @@ public TestRenderer(IRenderedComponentActivator renderedComponentActivator, Test logger = loggerFactory.CreateLogger(); this.activator = renderedComponentActivator; } -#endif /// public IRenderedFragmentBase RenderFragment(RenderFragment renderFragment) @@ -104,8 +78,7 @@ public IRenderedFragmentBase RenderFragment(RenderFragment renderFragment) public IRenderedComponentBase RenderComponent(ComponentParameterCollection parameters) where TComponent : IComponent { - if (parameters is null) - throw new ArgumentNullException(nameof(parameters)); + ArgumentNullException.ThrowIfNull(parameters); var renderFragment = parameters.ToRenderFragment(); return Render(renderFragment, id => activator.CreateRenderedComponent(id)); @@ -117,29 +90,23 @@ public IRenderedComponentBase RenderComponent(ComponentP EventFieldInfo fieldInfo, EventArgs eventArgs) => DispatchEventAsync(eventHandlerId, fieldInfo, eventArgs, ignoreUnknownEventHandlers: false); + /// /// -#if !NET8_0_OR_GREATER - public Task DispatchEventAsync( -#else public new Task DispatchEventAsync( -#endif ulong eventHandlerId, EventFieldInfo fieldInfo, EventArgs eventArgs, bool ignoreUnknownEventHandlers) { - if (fieldInfo is null) - throw new ArgumentNullException(nameof(fieldInfo)); + ArgumentNullException.ThrowIfNull(fieldInfo); - if (disposed) - throw new ObjectDisposedException(nameof(TestRenderer)); + ObjectDisposedException.ThrowIf(disposed, this); // Calling base.DispatchEventAsync updates the render tree // if the event contains associated data. lock (renderTreeUpdateLock) { - if (disposed) - throw new ObjectDisposedException(nameof(TestRenderer)); + ObjectDisposedException.ThrowIf(disposed, this); var result = Dispatcher.InvokeAsync(() => { @@ -191,8 +158,7 @@ public IReadOnlyList> FindComponents public void DisposeComponents() { - if (disposed) - throw new ObjectDisposedException(nameof(TestRenderer)); + ObjectDisposedException.ThrowIf(disposed, this); lock (renderTreeUpdateLock) { @@ -215,7 +181,6 @@ public void DisposeComponents() } } -#if NET8_0_OR_GREATER /// protected override IComponent ResolveComponentForRenderMode(Type componentType, int? parentComponentId, IComponentActivator componentActivator, IComponentRenderMode renderMode) @@ -224,13 +189,11 @@ protected override IComponent ResolveComponentForRenderMode(Type componentType, ArgumentNullException.ThrowIfNull(componentActivator); return componentActivator.CreateInstance(componentType); } -#endif /// internal Task SetDirectParametersAsync(IRenderedFragmentBase renderedComponent, ParameterView parameters) { - if (disposed) - throw new ObjectDisposedException(nameof(TestRenderer)); + ObjectDisposedException.ThrowIf(disposed, this); var result = Dispatcher.InvokeAsync(() => { @@ -260,20 +223,11 @@ internal Task SetDirectParametersAsync(IRenderedFragmentBase renderedComponent, return result; -#if NET8_0_OR_GREATER static void SetDirectParametersViaComponentState(TestRenderer renderer, int componentId, in ParameterView parameters) { var componentState = renderer.GetComponentState(componentId); CallSetDirectParameters(componentState, parameters); } -#else - static void SetDirectParametersViaComponentState(TestRenderer renderer, int componentId, in ParameterView parameters) - { - var componentState = GetRequiredComponentStateMethod.Invoke(renderer, new object[] { componentId })!; - var setDirectParametersMethod = componentState.GetType().GetMethod("SetDirectParameters", BindingFlags.Public | BindingFlags.Instance)!; - setDirectParametersMethod.Invoke(componentState, new object[] { parameters }); - } -#endif } /// @@ -447,8 +401,7 @@ protected override void Dispose(bool disposing) private TResult Render(RenderFragment renderFragment, Func activator) where TResult : IRenderedFragmentBase { - if (disposed) - throw new ObjectDisposedException(nameof(TestRenderer)); + ObjectDisposedException.ThrowIf(disposed, this); var renderTask = Dispatcher.InvokeAsync(() => { @@ -482,14 +435,12 @@ private TResult Render(RenderFragment renderFragment, Func> FindComponents(IRenderedFragmentBase parentComponent, int resultLimit) + private List> FindComponents(IRenderedFragmentBase parentComponent, int resultLimit) where TComponent : IComponent { - if (parentComponent is null) - throw new ArgumentNullException(nameof(parentComponent)); + ArgumentNullException.ThrowIfNull(parentComponent); - if (disposed) - throw new ObjectDisposedException(nameof(TestRenderer)); + ObjectDisposedException.ThrowIf(disposed, this); var result = new List>(); var framesCollection = new RenderTreeFrameDictionary(); @@ -498,8 +449,7 @@ private IReadOnlyList> FindComponentsFake version of the StringSyntaxAttribute, which was introduced in .NET 7 -[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] -[SuppressMessage("Design", "CA1019:Define accessors for attribute arguments", Justification = "The sole purpose is to have the same public surface as the class in .NET7 and above.")] -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.core/System.Diagnostics.CodeAnalysis/MemberNotNullAttribute.cs b/src/bunit.core/System.Diagnostics.CodeAnalysis/MemberNotNullAttribute.cs deleted file mode 100644 index 03049753a..000000000 --- a/src/bunit.core/System.Diagnostics.CodeAnalysis/MemberNotNullAttribute.cs +++ /dev/null @@ -1,29 +0,0 @@ -#if NETSTANDARD2_1 -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Diagnostics.CodeAnalysis; - -/// -/// Specifies that the method or property will ensure that the listed field and property members have not-null values. -/// -[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] -internal sealed class MemberNotNullAttribute : Attribute -{ - /// Initializes the attribute with a field or property member. - /// - /// The field or property member that is promised to be not-null. - /// - [SuppressMessage("Design", "CA1019:Define accessors for attribute arguments", Justification = "Copied from dotnet team.")] - public MemberNotNullAttribute(string member) => Members = new[] { member }; - - /// Initializes the attribute with the list of field and property members. - /// - /// The list of field and property members that are promised to be not-null. - /// - public MemberNotNullAttribute(params string[] members) => Members = members; - - /// Gets field or property member names. - public string[] Members { get; } -} -#endif diff --git a/src/bunit.core/TestContextBase.cs b/src/bunit.core/TestContextBase.cs index 9c2fa1e8a..cd660e5f8 100644 --- a/src/bunit.core/TestContextBase.cs +++ b/src/bunit.core/TestContextBase.cs @@ -42,7 +42,6 @@ public abstract class TestContextBase : IDisposable /// public RootRenderTree RenderTree { get; } = new(); -#if NET5_0_OR_GREATER /// /// Gets the . Factories added to it /// will be used to create components during testing, starting with the last added @@ -50,7 +49,6 @@ public abstract class TestContextBase : IDisposable /// then the default Blazor factory is used. /// public ComponentFactoryCollection ComponentFactories { get; } = new(); -#endif /// /// Initializes a new instance of the class. @@ -58,9 +56,7 @@ public abstract class TestContextBase : IDisposable protected TestContextBase() { Services = new TestServiceProvider(); -#if NET5_0_OR_GREATER Services.AddSingleton(_ => ComponentFactories); -#endif } /// diff --git a/src/bunit.core/TestDoubles/PersistentComponentState/FakePersistentComponentState.cs b/src/bunit.core/TestDoubles/PersistentComponentState/FakePersistentComponentState.cs index ff69fbf08..d10c717b3 100644 --- a/src/bunit.core/TestDoubles/PersistentComponentState/FakePersistentComponentState.cs +++ b/src/bunit.core/TestDoubles/PersistentComponentState/FakePersistentComponentState.cs @@ -1,13 +1,6 @@ -#if NET6_0_OR_GREATER -using System; -using System.Diagnostics.CodeAnalysis; using System.Text.Json; -using System.Threading.Tasks; using Bunit.Rendering; -using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Infrastructure; -using Microsoft.AspNetCore.Components.RenderTree; -using Microsoft.Extensions.DependencyInjection; namespace Bunit.TestDoubles; @@ -66,8 +59,7 @@ public void TriggerOnPersisting() /// The instance to persist. public void Persist(string key, TValue instance) { - if (key is null) - throw new ArgumentNullException(nameof(key)); + ArgumentNullException.ThrowIfNull(key); store.Add(key, JsonSerializer.SerializeToUtf8Bytes(instance, JsonSerializerOptions)); manager.Value.RestoreStateAsync(store); @@ -88,4 +80,3 @@ public void Persist(string key, TValue instance) public bool TryTake(string key, [MaybeNullWhen(false)] out TValue? instance) => manager.Value.State.TryTakeFromJson(key, out instance); } -#endif diff --git a/src/bunit.core/TestDoubles/PersistentComponentState/FakePersistentComponentStateStore.cs b/src/bunit.core/TestDoubles/PersistentComponentState/FakePersistentComponentStateStore.cs index b2cd2fa32..15705494a 100644 --- a/src/bunit.core/TestDoubles/PersistentComponentState/FakePersistentComponentStateStore.cs +++ b/src/bunit.core/TestDoubles/PersistentComponentState/FakePersistentComponentStateStore.cs @@ -1,9 +1,3 @@ -#if NET6_0_OR_GREATER -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Components; - namespace Bunit.TestDoubles; internal class FakePersistentComponentStateStore : IPersistentComponentStateStore @@ -28,4 +22,3 @@ public Task PersistStateAsync(IReadOnlyDictionary state) return Task.CompletedTask; } } -#endif diff --git a/src/bunit.core/TestDoubles/PersistentComponentState/TestContextBaseExtensions.cs b/src/bunit.core/TestDoubles/PersistentComponentState/TestContextBaseExtensions.cs index ea5717f5b..2ed1e3dbf 100644 --- a/src/bunit.core/TestDoubles/PersistentComponentState/TestContextBaseExtensions.cs +++ b/src/bunit.core/TestDoubles/PersistentComponentState/TestContextBaseExtensions.cs @@ -1,8 +1,4 @@ -#if NET6_0_OR_GREATER -using System; -using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Infrastructure; -using Microsoft.Extensions.DependencyInjection; namespace Bunit.TestDoubles; @@ -18,12 +14,10 @@ public static class TestContextBaseExtensions /// The added . public static FakePersistentComponentState AddFakePersistentComponentState(this TestContextBase testContext) { - if (testContext is null) - throw new ArgumentNullException(nameof(testContext)); + ArgumentNullException.ThrowIfNull(testContext); testContext.Services.AddSingleton(); testContext.Services.AddSingleton(s => s.GetRequiredService().State); return new FakePersistentComponentState(testContext.Services); } } -#endif diff --git a/src/bunit.core/TestServiceProvider.cs b/src/bunit.core/TestServiceProvider.cs index f4734786b..9e3054cbd 100644 --- a/src/bunit.core/TestServiceProvider.cs +++ b/src/bunit.core/TestServiceProvider.cs @@ -6,11 +6,7 @@ namespace Bunit; /// Represents a and /// as a single type used for test purposes. /// -#if !NET8_0_OR_GREATER -public sealed class TestServiceProvider : IServiceProvider, IServiceCollection, IDisposable, IAsyncDisposable -#else public sealed class TestServiceProvider : IKeyedServiceProvider, IServiceCollection, IDisposable, IAsyncDisposable -#endif { private static readonly ServiceProviderOptions DefaultServiceProviderOptions = new() { ValidateScopes = true }; private readonly IServiceCollection serviceCollection; @@ -77,10 +73,7 @@ private TestServiceProvider(IServiceCollection initialServiceCollection, bool in /// custom service provider factory public void UseServiceProviderFactory(Func serviceProviderFactory) { - if (serviceProviderFactory is null) - { - throw new ArgumentNullException(nameof(serviceProviderFactory)); - } + ArgumentNullException.ThrowIfNull(serviceProviderFactory); this.serviceProviderFactory = () => serviceProviderFactory(serviceCollection); } @@ -96,10 +89,7 @@ public void UseServiceProviderFactory(Func /// builder configuration action public void UseServiceProviderFactory(IServiceProviderFactory serviceProviderFactory, Action? configure = null) where TContainerBuilder : notnull { - if (serviceProviderFactory is null) - { - throw new ArgumentNullException(nameof(serviceProviderFactory)); - } + ArgumentNullException.ThrowIfNull(serviceProviderFactory); UseServiceProviderFactory(serviceCollection => { @@ -140,16 +130,9 @@ public void AddFallbackServiceProvider(IServiceProvider serviceProvider) /// A service object of type T or null if there is no such service. public TService? GetService() => (TService?)GetService(typeof(TService))!; -#if NETSTANDARD2_1 - /// - [return: MaybeNull] - public object GetService(Type serviceType) - => GetServiceInternal(serviceType); -#else /// public object? GetService(Type serviceType) => GetServiceInternal(serviceType); -#endif private object? GetServiceInternal(Type serviceType) { @@ -234,7 +217,6 @@ public bool Remove(ServiceDescriptor item) return serviceCollection.Remove(item); } -#if NET8_0_OR_GREATER /// public object? GetKeyedService(Type serviceType, object? serviceKey) { @@ -261,7 +243,6 @@ public object GetRequiredKeyedService(Type serviceType, object? serviceKey) return service; } -#endif private void CheckInitializedAndThrow() { diff --git a/src/bunit.core/bunit.core.csproj b/src/bunit.core/bunit.core.csproj index e1e8b2818..f50f7659f 100644 --- a/src/bunit.core/bunit.core.csproj +++ b/src/bunit.core/bunit.core.csproj @@ -1,7 +1,7 @@ - netstandard2.1;net5.0;net6.0;net7.0;net8.0;net9.0 + net8.0;net9.0 Bunit Bunit.Core @@ -14,30 +14,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/bunit.generators/Web.Stubs/AttributeStubGenerator/ComponentStubAttribute.cs b/src/bunit.generators/Web.Stubs/AttributeStubGenerator/ComponentStubAttribute.cs index f8c809770..e4ce56393 100644 --- a/src/bunit.generators/Web.Stubs/AttributeStubGenerator/ComponentStubAttribute.cs +++ b/src/bunit.generators/Web.Stubs/AttributeStubGenerator/ComponentStubAttribute.cs @@ -5,7 +5,6 @@ internal static class ComponentStubAttribute public static string ComponentStubAttributeSource = $$""" {{HeaderProvider.Header}} - #if NET5_0_OR_GREATER namespace Bunit; /// @@ -16,6 +15,5 @@ internal sealed class ComponentStubAttribute : global::System.Attribute where T : global::Microsoft.AspNetCore.Components.IComponent { } - #endif """; } diff --git a/src/bunit.web.query/bunit.web.query.csproj b/src/bunit.web.query/bunit.web.query.csproj index 1fedede0d..0fded8cba 100644 --- a/src/bunit.web.query/bunit.web.query.csproj +++ b/src/bunit.web.query/bunit.web.query.csproj @@ -1,7 +1,7 @@ - netstandard2.1;net5.0;net6.0;net7.0;net8.0;net9.0 + net8.0;net9.0 Bunit Bunit.Web.Query @@ -14,34 +14,6 @@ - - - - - - all - runtime; build; native; contentfiles; analyzers - - - - - - - - - - - - - - - - - - - - - diff --git a/src/bunit.web/Asserting/CompareToExtensions.cs b/src/bunit.web/Asserting/CompareToExtensions.cs index ca0e7ffe6..bb30c2137 100644 --- a/src/bunit.web/Asserting/CompareToExtensions.cs +++ b/src/bunit.web/Asserting/CompareToExtensions.cs @@ -18,10 +18,8 @@ public static class CompareToExtensions /// Any differences found. public static IReadOnlyList CompareTo(this IRenderedFragment actual, string expected) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); var htmlParser = actual.Services.GetRequiredService(); var expectedNodes = htmlParser.Parse(expected); @@ -38,10 +36,8 @@ public static IReadOnlyList CompareTo(this IRenderedFragment actual, stri /// Any differences found. public static IReadOnlyList CompareTo(this IRenderedFragment actual, IRenderedFragment expected) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); return actual.Nodes.CompareTo(expected.Nodes); } @@ -55,10 +51,8 @@ public static IReadOnlyList CompareTo(this IRenderedFragment actual, IRen /// Any differences found. public static IReadOnlyList CompareTo(this INode actual, INodeList expected) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); var comparer = actual.GetHtmlComparer(); @@ -74,10 +68,8 @@ public static IReadOnlyList CompareTo(this INode actual, INodeList expect /// Any differences found. public static IReadOnlyList CompareTo(this INodeList actual, INode expected) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); var comparer = expected.GetHtmlComparer(); @@ -93,10 +85,8 @@ public static IReadOnlyList CompareTo(this INodeList actual, INode expect /// Any differences found. public static IReadOnlyList CompareTo(this INodeList actual, INodeList expected) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); if (actual.Length == 0 && expected.Length == 0) return Array.Empty(); diff --git a/src/bunit.web/Asserting/DiffAssertExtensions.cs b/src/bunit.web/Asserting/DiffAssertExtensions.cs index 10c473006..6a41a9547 100644 --- a/src/bunit.web/Asserting/DiffAssertExtensions.cs +++ b/src/bunit.web/Asserting/DiffAssertExtensions.cs @@ -16,8 +16,7 @@ public static class DiffAssertExtensions /// The expected single in the collection. public static IDiff ShouldHaveSingleChange(this IEnumerable diffs) { - if (diffs is null) - throw new ArgumentNullException(nameof(diffs)); + ArgumentNullException.ThrowIfNull(diffs); var diffsArray = diffs.ToArray(); @@ -41,10 +40,8 @@ public static IDiff ShouldHaveSingleChange(this IEnumerable diffs) /// The total number of inspectors must exactly match the number of s in the collection. public static void ShouldHaveChanges(this IEnumerable diffs, params Action[] diffInspectors) { - if (diffs is null) - throw new ArgumentNullException(nameof(diffs)); - if (diffInspectors is null) - throw new ArgumentNullException(nameof(diffInspectors)); + ArgumentNullException.ThrowIfNull(diffs); + ArgumentNullException.ThrowIfNull(diffInspectors); var diffsArray = diffs.ToArray(); diff --git a/src/bunit.web/Asserting/FocusAsyncAssertJSInteropExtensions.cs b/src/bunit.web/Asserting/FocusAsyncAssertJSInteropExtensions.cs index cbbba528e..284ee732e 100644 --- a/src/bunit.web/Asserting/FocusAsyncAssertJSInteropExtensions.cs +++ b/src/bunit.web/Asserting/FocusAsyncAssertJSInteropExtensions.cs @@ -1,7 +1,4 @@ -#if NET5_0_OR_GREATER -using System.Collections.Generic; using Bunit.JSInterop.InvocationHandlers.Implementation; -using Microsoft.AspNetCore.Components; namespace Bunit; @@ -29,4 +26,3 @@ public static JSRuntimeInvocation VerifyFocusAsyncInvoke(this BunitJSInterop han public static IReadOnlyList VerifyFocusAsyncInvoke(this BunitJSInterop handler, int calledTimes, string? userMessage = null) => handler.VerifyInvoke(FocusAsyncInvocationHandler.FocusIdentifier, calledTimes, userMessage); } -#endif diff --git a/src/bunit.web/Asserting/FocusOnNavigateAssertJSInteropExtensions.cs b/src/bunit.web/Asserting/FocusOnNavigateAssertJSInteropExtensions.cs index 4e46c1710..c44397d5d 100644 --- a/src/bunit.web/Asserting/FocusOnNavigateAssertJSInteropExtensions.cs +++ b/src/bunit.web/Asserting/FocusOnNavigateAssertJSInteropExtensions.cs @@ -1,5 +1,3 @@ -#if NET6_0_OR_GREATER -using System.Collections.Generic; using Bunit.JSInterop.InvocationHandlers.Implementation; using Microsoft.AspNetCore.Components.Routing; @@ -29,4 +27,3 @@ public static JSRuntimeInvocation VerifyFocusOnNavigateInvoke(this BunitJSIntero public static IReadOnlyList VerifyFocusOnNavigateInvoke(this BunitJSInterop handler, int calledTimes, string? userMessage = null) => handler.VerifyInvoke(FocusOnNavigateHandler.Identifier, calledTimes, userMessage); } -#endif diff --git a/src/bunit.web/Asserting/JSInvokeCountExpectedException.cs b/src/bunit.web/Asserting/JSInvokeCountExpectedException.cs index 856cef937..0e37ec1ee 100644 --- a/src/bunit.web/Asserting/JSInvokeCountExpectedException.cs +++ b/src/bunit.web/Asserting/JSInvokeCountExpectedException.cs @@ -35,21 +35,17 @@ public JSInvokeCountExpectedException(string identifier, int expectedCount, int private JSInvokeCountExpectedException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { - if (serializationInfo is null) - throw new ArgumentNullException(nameof(serializationInfo)); + ArgumentNullException.ThrowIfNull(serializationInfo); ExpectedInvocationCount = serializationInfo.GetInt32(nameof(ExpectedInvocationCount)); ActualInvocationCount = serializationInfo.GetInt32(nameof(ActualInvocationCount)); Identifier = serializationInfo.GetString(nameof(Identifier)) ?? string.Empty; } /// -#if NET8_0_OR_GREATER [Obsolete("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] -#endif public override void GetObjectData(SerializationInfo info, StreamingContext context) { - if (info is null) - throw new ArgumentNullException(nameof(info)); + ArgumentNullException.ThrowIfNull(info); info.AddValue(nameof(ExpectedInvocationCount), ExpectedInvocationCount); info.AddValue(nameof(ActualInvocationCount), ActualInvocationCount); diff --git a/src/bunit.web/Asserting/JSRuntimeAssertExtensions.cs b/src/bunit.web/Asserting/JSRuntimeAssertExtensions.cs index 7bac76a88..de502e0c5 100644 --- a/src/bunit.web/Asserting/JSRuntimeAssertExtensions.cs +++ b/src/bunit.web/Asserting/JSRuntimeAssertExtensions.cs @@ -77,10 +77,8 @@ public static IReadOnlyList VerifyInvoke(this JSRu /// expected targeted element. public static void ShouldBeElementReferenceTo(this object? actualArgument, IElement expectedTargetElement) { - if (actualArgument is null) - throw new ArgumentNullException(nameof(actualArgument)); - if (expectedTargetElement is null) - throw new ArgumentNullException(nameof(expectedTargetElement)); + ArgumentNullException.ThrowIfNull(actualArgument); + ArgumentNullException.ThrowIfNull(expectedTargetElement); if (actualArgument is not ElementReference elmRef) throw new ActualExpectedAssertException(actualArgument.GetType().Name, nameof(ElementReference), "Actual argument type", "Expected argument type", $"The argument was not an {nameof(ElementReference)}"); diff --git a/src/bunit.web/Asserting/MarkupMatchesAssertExtensions.cs b/src/bunit.web/Asserting/MarkupMatchesAssertExtensions.cs index a52b1e002..8cb96e004 100644 --- a/src/bunit.web/Asserting/MarkupMatchesAssertExtensions.cs +++ b/src/bunit.web/Asserting/MarkupMatchesAssertExtensions.cs @@ -23,10 +23,8 @@ public static class MarkupMatchesAssertExtensions [AssertionMethod] 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)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); using var parser = new BunitHtmlParser(); var actualNodes = parser.Parse(actual); @@ -45,10 +43,8 @@ public static void MarkupMatches([StringSyntax("Html")]this string actual, [Stri [AssertionMethod] public static void MarkupMatches([StringSyntax("Html")]this string actual, IRenderedFragment expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); var actualNodes = actual.ToNodeList(expected.Services.GetRequiredService()); actualNodes.MarkupMatches(expected, userMessage); @@ -65,10 +61,8 @@ public static void MarkupMatches([StringSyntax("Html")]this string actual, IRend [AssertionMethod] public static void MarkupMatches([StringSyntax("Html")]this string actual, INodeList expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); var actualNodes = actual.ToNodeList(expected.GetHtmlParser()); actualNodes.MarkupMatches(expected, userMessage); @@ -85,10 +79,8 @@ public static void MarkupMatches([StringSyntax("Html")]this string actual, INode [AssertionMethod] public static void MarkupMatches([StringSyntax("Html")]this string actual, INode expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); var actualNodes = actual.ToNodeList(expected.GetHtmlParser()); actualNodes.MarkupMatches(expected, userMessage); @@ -105,10 +97,8 @@ public static void MarkupMatches([StringSyntax("Html")]this string actual, INode [AssertionMethod] public static void MarkupMatches(this IRenderedFragment actual, [StringSyntax("Html")]string expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); var expectedNodes = expected.ToNodeList(actual.Services.GetRequiredService()); actual.Nodes.MarkupMatches(expectedNodes, userMessage); @@ -125,10 +115,8 @@ public static void MarkupMatches(this IRenderedFragment actual, [StringSyntax("H [AssertionMethod] public static void MarkupMatches(this IRenderedFragment actual, IRenderedFragment expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); actual.Nodes.MarkupMatches(expected.Nodes, userMessage); } @@ -145,10 +133,8 @@ public static void MarkupMatches(this IRenderedFragment actual, IRenderedFragmen [AssertionMethod] public static void MarkupMatches(this INodeList actual, IRenderedFragment expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); actual.MarkupMatches(expected.Nodes, userMessage); } @@ -165,10 +151,8 @@ public static void MarkupMatches(this INodeList actual, IRenderedFragment expect [AssertionMethod] public static void MarkupMatches(this INode actual, IRenderedFragment expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); actual.MarkupMatches(expected.Nodes, userMessage); } @@ -185,10 +169,8 @@ public static void MarkupMatches(this INode actual, IRenderedFragment expected, [AssertionMethod] public static void MarkupMatches(this INode actual, [StringSyntax("Html")]string expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); var expectedNodes = expected.ToNodeList(actual.GetHtmlParser()); actual.MarkupMatches(expectedNodes, userMessage); @@ -206,10 +188,8 @@ public static void MarkupMatches(this INode actual, [StringSyntax("Html")]string [AssertionMethod] public static void MarkupMatches(this INodeList actual, [StringSyntax("Html")]string expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); var expectedNodes = expected.ToNodeList(actual.GetHtmlParser()); actual.MarkupMatches(expectedNodes, userMessage); @@ -227,10 +207,8 @@ public static void MarkupMatches(this INodeList actual, [StringSyntax("Html")]st [AssertionMethod] public static void MarkupMatches(this INodeList actual, INodeList expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); var diffs = actual.CompareTo(expected); @@ -250,10 +228,8 @@ public static void MarkupMatches(this INodeList actual, INodeList expected, stri [AssertionMethod] public static void MarkupMatches(this INodeList actual, INode expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); var diffs = actual.CompareTo(expected); @@ -273,10 +249,8 @@ public static void MarkupMatches(this INodeList actual, INode expected, string? [AssertionMethod] public static void MarkupMatches(this INode actual, INodeList expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); var diffs = actual.CompareTo(expected); @@ -295,10 +269,8 @@ public static void MarkupMatches(this INode actual, INodeList expected, string? [AssertionMethod] public static void MarkupMatches(this IRenderedFragment actual, RenderFragment expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); // TODO: This will be obsolete with: https://github.com/bUnit-dev/bUnit/issues/1018 // As the renderer would be transient we don't have to new up an instance @@ -321,10 +293,8 @@ public static void MarkupMatches(this IRenderedFragment actual, RenderFragment e [AssertionMethod] public static void MarkupMatches(this INode actual, RenderFragment expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); var renderedFragment = actual.GetTestContext()?.RenderInsideRenderTree(expected) as IRenderedFragment ?? AdhocRenderRenderFragment(expected); @@ -342,10 +312,8 @@ public static void MarkupMatches(this INode actual, RenderFragment expected, str [AssertionMethod] public static void MarkupMatches(this INodeList actual, RenderFragment expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); var renderedFragment = actual.GetTestContext()?.RenderInsideRenderTree(expected) as IRenderedFragment ?? AdhocRenderRenderFragment(expected); @@ -363,10 +331,8 @@ public static void MarkupMatches(this INodeList actual, RenderFragment expected, [AssertionMethod] public static void MarkupMatches(this IEnumerable actual, [StringSyntax("Html")]string expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); MarkupMatches(actual.ToNodeList(), expected, userMessage); } @@ -382,10 +348,8 @@ public static void MarkupMatches(this IEnumerable actual, [StringSynta [AssertionMethod] public static void MarkupMatches(this IElement actual, IEnumerable expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); var expectedNodes = string.Join(string.Empty, expected.Select(e => e.Markup)); @@ -403,10 +367,8 @@ public static void MarkupMatches(this IElement actual, IEnumerable expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); var expectedNodes = expected.ToNodeList(); @@ -424,10 +386,8 @@ public static void MarkupMatches(this IElement actual, IEnumerable exp [AssertionMethod] public static void MarkupMatches(this IEnumerable actual, IRenderedFragment expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); MarkupMatches(actual.ToNodeList(), expected, userMessage); } @@ -443,10 +403,8 @@ public static void MarkupMatches(this IEnumerable actual, IRenderedFra [AssertionMethod] public static void MarkupMatches(this IEnumerable actual, IEnumerable expected, string? userMessage = null) { - if (actual is null) - throw new ArgumentNullException(nameof(actual)); - if (expected is null) - throw new ArgumentNullException(nameof(expected)); + ArgumentNullException.ThrowIfNull(actual); + ArgumentNullException.ThrowIfNull(expected); var expectedNodes = string.Join(string.Empty, expected.Select(e => e.Markup)); diff --git a/src/bunit.web/Asserting/ShouldBeAdditionAssertExtensions.cs b/src/bunit.web/Asserting/ShouldBeAdditionAssertExtensions.cs index 0dd6e2308..bcf8df9ba 100644 --- a/src/bunit.web/Asserting/ShouldBeAdditionAssertExtensions.cs +++ b/src/bunit.web/Asserting/ShouldBeAdditionAssertExtensions.cs @@ -19,10 +19,8 @@ public static class ShouldBeAdditionAssertExtensions /// A custom user message to display in case the verification fails. public static void ShouldBeAddition(this IDiff actualChange, string expectedChange, string? userMessage = null) { - if (actualChange is null) - throw new ArgumentNullException(nameof(actualChange)); - if (expectedChange is null) - throw new ArgumentNullException(nameof(expectedChange)); + ArgumentNullException.ThrowIfNull(actualChange); + ArgumentNullException.ThrowIfNull(expectedChange); if (actualChange is not UnexpectedNodeDiff actual) throw new DiffChangeAssertException(actualChange.Result, DiffResult.Unexpected, "The change was not an addition."); @@ -50,8 +48,7 @@ public static void ShouldBeAddition(this IDiff actualChange, string expectedChan /// A custom user message to display in case the verification fails. public static void ShouldBeAddition(this IDiff actualChange, IRenderedFragment expectedChange, string? userMessage = null) { - if (expectedChange is null) - throw new ArgumentNullException(nameof(expectedChange)); + ArgumentNullException.ThrowIfNull(expectedChange); ShouldBeAddition(actualChange, expectedChange.Nodes, userMessage); } @@ -65,10 +62,8 @@ public static void ShouldBeAddition(this IDiff actualChange, IRenderedFragment e /// A custom user message to display in case the verification fails. public static void ShouldBeAddition(this IDiff actualChange, INodeList expectedChange, string? userMessage = null) { - if (actualChange is null) - throw new ArgumentNullException(nameof(actualChange)); - if (expectedChange is null) - throw new ArgumentNullException(nameof(expectedChange)); + ArgumentNullException.ThrowIfNull(actualChange); + ArgumentNullException.ThrowIfNull(expectedChange); if (actualChange is not UnexpectedNodeDiff actual) throw new DiffChangeAssertException(actualChange.Result, DiffResult.Unexpected, "The change was not an addition."); diff --git a/src/bunit.web/Asserting/ShouldBeRemovalAssertExtensions.cs b/src/bunit.web/Asserting/ShouldBeRemovalAssertExtensions.cs index 9b121dc18..d37cc6f52 100644 --- a/src/bunit.web/Asserting/ShouldBeRemovalAssertExtensions.cs +++ b/src/bunit.web/Asserting/ShouldBeRemovalAssertExtensions.cs @@ -19,10 +19,8 @@ public static class ShouldBeRemovalAssertExtensions /// A custom user message to display in case the verification fails. public static void ShouldBeRemoval(this IDiff actualChange, string expectedChange, string? userMessage = null) { - if (actualChange is null) - throw new ArgumentNullException(nameof(actualChange)); - if (expectedChange is null) - throw new ArgumentNullException(nameof(expectedChange)); + ArgumentNullException.ThrowIfNull(actualChange); + ArgumentNullException.ThrowIfNull(expectedChange); if (actualChange is not MissingNodeDiff actual) throw new DiffChangeAssertException(actualChange.Result, DiffResult.Missing, "The change was not an removal."); @@ -50,8 +48,7 @@ public static void ShouldBeRemoval(this IDiff actualChange, string expectedChang /// A custom user message to display in case the verification fails. public static void ShouldBeRemoval(this IDiff actualChange, IRenderedFragment expectedChange, string? userMessage = null) { - if (expectedChange is null) - throw new ArgumentNullException(nameof(expectedChange)); + ArgumentNullException.ThrowIfNull(expectedChange); ShouldBeRemoval(actualChange, expectedChange.Nodes, userMessage); } @@ -65,10 +62,8 @@ public static void ShouldBeRemoval(this IDiff actualChange, IRenderedFragment ex /// A custom user message to display in case the verification fails. public static void ShouldBeRemoval(this IDiff actualChange, INodeList expectedChange, string? userMessage = null) { - if (actualChange is null) - throw new ArgumentNullException(nameof(actualChange)); - if (expectedChange is null) - throw new ArgumentNullException(nameof(expectedChange)); + ArgumentNullException.ThrowIfNull(actualChange); + ArgumentNullException.ThrowIfNull(expectedChange); if (actualChange is not MissingNodeDiff actual) throw new DiffChangeAssertException(actualChange.Result, DiffResult.Missing, "The change was not an removal."); diff --git a/src/bunit.web/Asserting/ShouldBeTextChangeAssertExtensions.cs b/src/bunit.web/Asserting/ShouldBeTextChangeAssertExtensions.cs index 395ebc274..da270c64c 100644 --- a/src/bunit.web/Asserting/ShouldBeTextChangeAssertExtensions.cs +++ b/src/bunit.web/Asserting/ShouldBeTextChangeAssertExtensions.cs @@ -29,10 +29,8 @@ public static void ShouldHaveSingleTextChange(this IEnumerable diffs, str /// A custom error message to show if the verification fails. public static void ShouldBeTextChange(this IDiff actualChange, string expectedChange, string? userMessage = null) { - if (actualChange is null) - throw new ArgumentNullException(nameof(actualChange)); - if (expectedChange is null) - throw new ArgumentNullException(nameof(expectedChange)); + ArgumentNullException.ThrowIfNull(actualChange); + ArgumentNullException.ThrowIfNull(expectedChange); if (actualChange is not NodeDiff actual) throw new DiffChangeAssertException(actualChange.Result, DiffResult.Different, "The change was not a text change."); @@ -57,8 +55,7 @@ public static void ShouldBeTextChange(this IDiff actualChange, string expectedCh /// A custom error message to show if the verification fails. public static void ShouldBeTextChange(this IDiff actualChange, IRenderedFragment expectedChange, string? userMessage = null) { - if (expectedChange is null) - throw new ArgumentNullException(nameof(expectedChange)); + ArgumentNullException.ThrowIfNull(expectedChange); ShouldBeTextChange(actualChange, expectedChange.Nodes, userMessage); } @@ -70,10 +67,8 @@ public static void ShouldBeTextChange(this IDiff actualChange, IRenderedFragment /// A custom error message to show if the verification fails. public static void ShouldBeTextChange(this IDiff actualChange, INodeList expectedChange, string? userMessage = null) { - if (actualChange is null) - throw new ArgumentNullException(nameof(actualChange)); - if (expectedChange is null) - throw new ArgumentNullException(nameof(expectedChange)); + ArgumentNullException.ThrowIfNull(actualChange); + ArgumentNullException.ThrowIfNull(expectedChange); if (actualChange is not NodeDiff actual) throw new DiffChangeAssertException(actualChange.Result, DiffResult.Different, "The change was not a text change."); @@ -96,12 +91,9 @@ public static void ShouldBeTextChange(this IDiff actualChange, INodeList expecte /// A custom user message to show when the verification fails. public static void ShouldBeAttributeChange(this IDiff actualChange, string expectedAttrName, string expectedAttrValue, string? userMessage = null) { - if (actualChange is null) - throw new ArgumentNullException(nameof(actualChange)); - if (expectedAttrName is null) - throw new ArgumentNullException(nameof(expectedAttrName)); - if (expectedAttrValue is null) - throw new ArgumentNullException(nameof(expectedAttrValue)); + ArgumentNullException.ThrowIfNull(actualChange); + ArgumentNullException.ThrowIfNull(expectedAttrName); + ArgumentNullException.ThrowIfNull(expectedAttrValue); if (actualChange is not AttrDiff actual) throw new DiffChangeAssertException(actualChange.Result, DiffResult.Different, "The change was not a attribute change."); diff --git a/src/bunit.web/ComponentFactories/StubComponentFactory.cs b/src/bunit.web/ComponentFactories/StubComponentFactory.cs index dc2319845..b7145d751 100644 --- a/src/bunit.web/ComponentFactories/StubComponentFactory.cs +++ b/src/bunit.web/ComponentFactories/StubComponentFactory.cs @@ -1,4 +1,3 @@ -#if NET5_0_OR_GREATER using Bunit.TestDoubles; namespace Bunit.ComponentFactories; @@ -25,4 +24,3 @@ public IComponent Create(Type componentType) return (IComponent)Activator.CreateInstance(typeToCreate, replacementContent)!; } } -#endif diff --git a/src/bunit.web/Diffing/DiffMarkupFormatter.cs b/src/bunit.web/Diffing/DiffMarkupFormatter.cs index ccb033627..e32fc2a36 100644 --- a/src/bunit.web/Diffing/DiffMarkupFormatter.cs +++ b/src/bunit.web/Diffing/DiffMarkupFormatter.cs @@ -37,8 +37,7 @@ public DiffMarkupFormatter() /// protected override string Attribute(IAttr attr) { - if (attr is null) - throw new ArgumentNullException(nameof(attr)); + ArgumentNullException.ThrowIfNull(attr); return Htmlizer.IsBlazorAttribute(attr.Name ?? string.Empty) ? string.Empty diff --git a/src/bunit.web/EventDispatchExtensions/DetailsElementEventDispatchExtensions.cs b/src/bunit.web/EventDispatchExtensions/DetailsElementEventDispatchExtensions.cs index 6fa6aecc7..37ffa5acf 100644 --- a/src/bunit.web/EventDispatchExtensions/DetailsElementEventDispatchExtensions.cs +++ b/src/bunit.web/EventDispatchExtensions/DetailsElementEventDispatchExtensions.cs @@ -1,6 +1,3 @@ -#if NET5_0_OR_GREATER -using System; -using System.Threading.Tasks; using AngleSharp.Dom; namespace Bunit; @@ -27,4 +24,3 @@ public static void Toggle(this IElement element) /// A task that completes when the event handler is done. public static Task ToggleAsync(this IElement element, EventArgs eventArgs) => element.TriggerEventAsync("ontoggle", eventArgs); } -#endif diff --git a/src/bunit.web/EventDispatchExtensions/DialogEventDispatchExtensions.cs b/src/bunit.web/EventDispatchExtensions/DialogEventDispatchExtensions.cs index 8dd6f3d7c..8fa2b9706 100644 --- a/src/bunit.web/EventDispatchExtensions/DialogEventDispatchExtensions.cs +++ b/src/bunit.web/EventDispatchExtensions/DialogEventDispatchExtensions.cs @@ -1,6 +1,5 @@ using AngleSharp.Dom; -#if NET8_0_OR_GREATER namespace Bunit; /// @@ -28,4 +27,3 @@ public static class DialogEventDispatchExtensions /// public static Task CloseAsync(this IElement element) => element.TriggerEventAsync("onclose", EventArgs.Empty); } -#endif diff --git a/src/bunit.web/EventDispatchExtensions/MouseEventDispatchExtensions.cs b/src/bunit.web/EventDispatchExtensions/MouseEventDispatchExtensions.cs index 67c7d30a3..d67a0b866 100644 --- a/src/bunit.web/EventDispatchExtensions/MouseEventDispatchExtensions.cs +++ b/src/bunit.web/EventDispatchExtensions/MouseEventDispatchExtensions.cs @@ -252,7 +252,6 @@ public static void MouseUp(this IElement element, MouseEventArgs eventArgs) /// A task that completes when the event handler is done. public static Task MouseUpAsync(this IElement element, MouseEventArgs eventArgs) => element.TriggerEventAsync("onmouseup", eventArgs); -#if NET6_0_OR_GREATER /// /// Raises the @onclick event on , passing the provided /// properties to the event handler via a object. @@ -287,72 +286,6 @@ public static void MouseUp(this IElement element, MouseEventArgs eventArgs) /// Gets or sets the type of the event. public static void Click(this IElement element, long detail = 1, double screenX = default, double screenY = default, double clientX = default, double clientY = default, double pageX = 0, double pageY = 0, double offsetX = 0, double offsetY = 0, long button = default, long buttons = default, bool ctrlKey = default, bool shiftKey = default, bool altKey = default, bool metaKey = default, string? type = default) => _ = ClickAsync(element, new MouseEventArgs { Detail = detail, ScreenX = screenX, ScreenY = screenY, ClientX = clientX, PageX = pageX, PageY = pageY, OffsetX = offsetX, OffsetY = offsetY, ClientY = clientY, Button = button, Buttons = buttons, CtrlKey = ctrlKey, ShiftKey = shiftKey, AltKey = altKey, MetaKey = metaKey, Type = type! }); -#elif NET5_0 - /// - /// Raises the @onclick event on , passing the provided - /// properties to the event handler via a object. - /// - /// The element to raise the event on. - /// A count of consecutive clicks that happened in a short amount of time, incremented by one. - /// The X coordinate of the mouse pointer in global (screen) coordinates. - /// The Y coordinate of the mouse pointer in global (screen) coordinates. - /// The X coordinate of the mouse pointer in local (DOM content) coordinates. - /// The Y coordinate of the mouse pointer in local (DOM content) coordinates. - /// The X coordinate of the mouse pointer in relative (Target Element) coordinates. - /// The Y coordinate of the mouse pointer in relative (Target Element) coordinates. - /// - /// The button number that was pressed when the mouse event was fired: Left button=0, - /// middle button=1 (if present), right button=2. For mice configured for left handed - /// use in which the button actions are reversed the values are instead read from - /// right to left. - /// - /// - /// The buttons being pressed when the mouse event was fired: Left button=1, Right - /// button=2, Middle (wheel) button=4, 4th button (typically, "Browser Back" button)=8, - /// 5th button (typically, "Browser Forward" button)=16. If two or more buttons are - /// pressed, returns the logical sum of the values. E.g., if Left button and Right - /// button are pressed, returns 3 (=1 | 2). - /// - /// true if the control key was down when the event was fired. false otherwise. - /// true if the shift key was down when the event was fired. false otherwise. - /// true if the alt key was down when the event was fired. false otherwise. - /// true if the meta key was down when the event was fired. false otherwise. - /// Gets or sets the type of the event. - public static void Click(this IElement element, long detail = 1, double screenX = default, double screenY = default, double clientX = default, double clientY = default, double offsetX = 0, double offsetY = 0, long button = default, long buttons = default, bool ctrlKey = default, bool shiftKey = default, bool altKey = default, bool metaKey = default, string? type = default) - => _ = ClickAsync(element, new MouseEventArgs { Detail = detail, ScreenX = screenX, ScreenY = screenY, ClientX = clientX, OffsetX = offsetX, OffsetY = offsetY, ClientY = clientY, Button = button, Buttons = buttons, CtrlKey = ctrlKey, ShiftKey = shiftKey, AltKey = altKey, MetaKey = metaKey, Type = type! }); -#else - /// - /// Raises the @onclick event on , passing the provided - /// properties to the event handler via a object. - /// - /// The element to raise the event on. - /// A count of consecutive clicks that happened in a short amount of time, incremented by one. - /// The X coordinate of the mouse pointer in global (screen) coordinates. - /// The Y coordinate of the mouse pointer in global (screen) coordinates. - /// The X coordinate of the mouse pointer in local (DOM content) coordinates. - /// The Y coordinate of the mouse pointer in local (DOM content) coordinates. - /// - /// The button number that was pressed when the mouse event was fired: Left button=0, - /// middle button=1 (if present), right button=2. For mice configured for left handed - /// use in which the button actions are reversed the values are instead read from - /// right to left. - /// - /// - /// The buttons being pressed when the mouse event was fired: Left button=1, Right - /// button=2, Middle (wheel) button=4, 4th button (typically, "Browser Back" button)=8, - /// 5th button (typically, "Browser Forward" button)=16. If two or more buttons are - /// pressed, returns the logical sum of the values. E.g., if Left button and Right - /// button are pressed, returns 3 (=1 | 2). - /// - /// true if the control key was down when the event was fired. false otherwise. - /// true if the shift key was down when the event was fired. false otherwise. - /// true if the alt key was down when the event was fired. false otherwise. - /// true if the meta key was down when the event was fired. false otherwise. - /// Gets or sets the type of the event. - public static void Click(this IElement element, long detail = 1, double screenX = default, double screenY = default, double clientX = default, double clientY = default, long button = default, long buttons = default, bool ctrlKey = default, bool shiftKey = default, bool altKey = default, bool metaKey = default, string? type = default) - => _ = ClickAsync(element, new MouseEventArgs { Detail = detail, ScreenX = screenX, ScreenY = screenY, ClientX = clientX, ClientY = clientY, Button = button, Buttons = buttons, CtrlKey = ctrlKey, ShiftKey = shiftKey, AltKey = altKey, MetaKey = metaKey, Type = type! }); -#endif - /// /// Raises the @onclick event on , passing the provided @@ -372,7 +305,6 @@ public static void Click(this IElement element, MouseEventArgs eventArgs) /// A task that completes when the event handler is done. public static Task ClickAsync(this IElement element, MouseEventArgs eventArgs) => element.TriggerEventAsync("onclick", eventArgs); -#if NET6_0_OR_GREATER /// /// Raises the @ondblclick event on , passing the provided /// properties to the event handler via a object. @@ -407,72 +339,7 @@ public static void Click(this IElement element, MouseEventArgs eventArgs) /// Gets or sets the type of the event. public static void DoubleClick(this IElement element, long detail = 2, double screenX = default, double screenY = default, double clientX = default, double clientY = default, double pageX = 0, double pageY = 0, double offsetX = 0, double offsetY = 0, long button = default, long buttons = default, bool ctrlKey = default, bool shiftKey = default, bool altKey = default, bool metaKey = default, string? type = default) => _ = DoubleClickAsync(element, new MouseEventArgs { Detail = detail, ScreenX = screenX, ScreenY = screenY, ClientX = clientX, ClientY = clientY, PageX = pageX, PageY = pageY, OffsetX = offsetX, OffsetY = offsetY, Button = button, Buttons = buttons, CtrlKey = ctrlKey, ShiftKey = shiftKey, AltKey = altKey, MetaKey = metaKey, Type = type! }); -#elif NET5_0 - /// - /// Raises the @ondblclick event on , passing the provided - /// properties to the event handler via a object. - /// - /// The element to raise the event on. - /// A count of consecutive clicks that happened in a short amount of time, incremented by one. - /// The X coordinate of the mouse pointer in global (screen) coordinates. - /// The Y coordinate of the mouse pointer in global (screen) coordinates. - /// The X coordinate of the mouse pointer in local (DOM content) coordinates. - /// The Y coordinate of the mouse pointer in local (DOM content) coordinates. - /// The X coordinate of the mouse pointer in relative (Target Element) coordinates. - /// The Y coordinate of the mouse pointer in relative (Target Element) coordinates. - /// - /// The button number that was pressed when the mouse event was fired: Left button=0, - /// middle button=1 (if present), right button=2. For mice configured for left handed - /// use in which the button actions are reversed the values are instead read from - /// right to left. - /// - /// - /// The buttons being pressed when the mouse event was fired: Left button=1, Right - /// button=2, Middle (wheel) button=4, 4th button (typically, "Browser Back" button)=8, - /// 5th button (typically, "Browser Forward" button)=16. If two or more buttons are - /// pressed, returns the logical sum of the values. E.g., if Left button and Right - /// button are pressed, returns 3 (=1 | 2). - /// - /// true if the control key was down when the event was fired. false otherwise. - /// true if the shift key was down when the event was fired. false otherwise. - /// true if the alt key was down when the event was fired. false otherwise. - /// true if the meta key was down when the event was fired. false otherwise. - /// Gets or sets the type of the event. - public static void DoubleClick(this IElement element, long detail = 2, double screenX = default, double screenY = default, double clientX = default, double clientY = default, double offsetX = 0, double offsetY = 0, long button = default, long buttons = default, bool ctrlKey = default, bool shiftKey = default, bool altKey = default, bool metaKey = default, string? type = default) - => _ = DoubleClickAsync(element, new MouseEventArgs { Detail = detail, ScreenX = screenX, ScreenY = screenY, ClientX = clientX, ClientY = clientY, OffsetX = offsetX, OffsetY = offsetY, Button = button, Buttons = buttons, CtrlKey = ctrlKey, ShiftKey = shiftKey, AltKey = altKey, MetaKey = metaKey, Type = type! }); -#else - /// - /// Raises the @ondblclick event on , passing the provided - /// properties to the event handler via a object. - /// - /// The element to raise the event on. - /// A count of consecutive clicks that happened in a short amount of time, incremented by one. - /// The X coordinate of the mouse pointer in global (screen) coordinates. - /// The Y coordinate of the mouse pointer in global (screen) coordinates. - /// The X coordinate of the mouse pointer in local (DOM content) coordinates. - /// The Y coordinate of the mouse pointer in local (DOM content) coordinates. - /// - /// The button number that was pressed when the mouse event was fired: Left button=0, - /// middle button=1 (if present), right button=2. For mice configured for left handed - /// use in which the button actions are reversed the values are instead read from - /// right to left. - /// - /// - /// The buttons being pressed when the mouse event was fired: Left button=1, Right - /// button=2, Middle (wheel) button=4, 4th button (typically, "Browser Back" button)=8, - /// 5th button (typically, "Browser Forward" button)=16. If two or more buttons are - /// pressed, returns the logical sum of the values. E.g., if Left button and Right - /// button are pressed, returns 3 (=1 | 2). - /// - /// true if the control key was down when the event was fired. false otherwise. - /// true if the shift key was down when the event was fired. false otherwise. - /// true if the alt key was down when the event was fired. false otherwise. - /// true if the meta key was down when the event was fired. false otherwise. - /// Gets or sets the type of the event. - public static void DoubleClick(this IElement element, long detail = 2, double screenX = default, double screenY = default, double clientX = default, double clientY = default, long button = default, long buttons = default, bool ctrlKey = default, bool shiftKey = default, bool altKey = default, bool metaKey = default, string? type = default) - => _ = DoubleClickAsync(element, new MouseEventArgs { Detail = detail, ScreenX = screenX, ScreenY = screenY, ClientX = clientX, ClientY = clientY, Button = button, Buttons = buttons, CtrlKey = ctrlKey, ShiftKey = shiftKey, AltKey = altKey, MetaKey = metaKey, Type = type! }); -#endif /// /// Raises the @ondblclick event on , passing the provided /// to the event handler. diff --git a/src/bunit.web/EventDispatchExtensions/TriggerEventDispatchExtensions.cs b/src/bunit.web/EventDispatchExtensions/TriggerEventDispatchExtensions.cs index 410072f34..2a243b8b1 100644 --- a/src/bunit.web/EventDispatchExtensions/TriggerEventDispatchExtensions.cs +++ b/src/bunit.web/EventDispatchExtensions/TriggerEventDispatchExtensions.cs @@ -59,15 +59,8 @@ public static void TriggerEvent(this IElement element, string eventName, EventAr /// A that completes when the render caused by the triggering of the event finishes. public static Task TriggerEventAsync(this IElement element, string eventName, EventArgs eventArgs) { - if (element is null) - { - throw new ArgumentNullException(nameof(element)); - } - - if (eventName is null) - { - throw new ArgumentNullException(nameof(eventName)); - } + ArgumentNullException.ThrowIfNull(element); + ArgumentNullException.ThrowIfNull(eventName); var renderer = element.GetTestContext()?.Renderer ?? throw new InvalidOperationException($"Blazor events can only be raised on elements rendered with the Blazor test renderer '{nameof(ITestRenderer)}'."); diff --git a/src/bunit.web/Extensions/ElementNotFoundException.cs b/src/bunit.web/Extensions/ElementNotFoundException.cs index 8d6d46af3..ea4ce0949 100644 --- a/src/bunit.web/Extensions/ElementNotFoundException.cs +++ b/src/bunit.web/Extensions/ElementNotFoundException.cs @@ -40,13 +40,10 @@ protected ElementNotFoundException(SerializationInfo serializationInfo, Streamin } /// -#if NET8_0_OR_GREATER [Obsolete("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] -#endif public override void GetObjectData(SerializationInfo info, StreamingContext context) { - if (info is null) - throw new ArgumentNullException(nameof(info)); + ArgumentNullException.ThrowIfNull(info); info.AddValue(nameof(CssSelector), CssSelector); base.GetObjectData(info, context); } diff --git a/src/bunit.web/Extensions/InputFile/BUnitBrowserFile.cs b/src/bunit.web/Extensions/InputFile/BUnitBrowserFile.cs index 76e5dc8ae..ee28fb743 100644 --- a/src/bunit.web/Extensions/InputFile/BUnitBrowserFile.cs +++ b/src/bunit.web/Extensions/InputFile/BUnitBrowserFile.cs @@ -1,5 +1,4 @@ -#if NET5_0_OR_GREATER -using Microsoft.AspNetCore.Components.Forms; +using Microsoft.AspNetCore.Components.Forms; namespace Bunit; @@ -30,4 +29,3 @@ public Stream OpenReadStream(long maxAllowedSize = 512000, CancellationToken can return new MemoryStream(Content); } } -#endif \ No newline at end of file diff --git a/src/bunit.web/Extensions/InputFile/InputFileContent.cs b/src/bunit.web/Extensions/InputFile/InputFileContent.cs index 6427e4bdf..1c45ab5a7 100644 --- a/src/bunit.web/Extensions/InputFile/InputFileContent.cs +++ b/src/bunit.web/Extensions/InputFile/InputFileContent.cs @@ -1,4 +1,3 @@ -#if NET5_0_OR_GREATER using System.Text; namespace Bunit; @@ -39,8 +38,7 @@ public static InputFileContent CreateFromText( DateTimeOffset? lastChanged = null, string? contentType = null) { - if (fileContent == null) - throw new ArgumentNullException(nameof(fileContent)); + ArgumentNullException.ThrowIfNull(fileContent); return new InputFileContent(Encoding.Default.GetBytes(fileContent), fileName, lastChanged, contentType); } @@ -58,10 +56,8 @@ public static InputFileContent CreateFromBinary( DateTimeOffset? lastChanged = null, string? contentType = null) { - if (fileContent == null) - throw new ArgumentNullException(nameof(fileContent)); + ArgumentNullException.ThrowIfNull(fileContent); return new InputFileContent(fileContent, fileName, lastChanged, contentType); } } -#endif \ No newline at end of file diff --git a/src/bunit.web/Extensions/InputFile/InputFileExtensions.cs b/src/bunit.web/Extensions/InputFile/InputFileExtensions.cs index 3eb0de24c..3d9f2e008 100644 --- a/src/bunit.web/Extensions/InputFile/InputFileExtensions.cs +++ b/src/bunit.web/Extensions/InputFile/InputFileExtensions.cs @@ -1,5 +1,4 @@ -#if NET5_0_OR_GREATER -using Microsoft.AspNetCore.Components.Forms; +using Microsoft.AspNetCore.Components.Forms; namespace Bunit; @@ -17,11 +16,9 @@ public static void UploadFiles( this IRenderedComponent inputFileComponent, params InputFileContent[] files) { - if (inputFileComponent == null) - throw new ArgumentNullException(nameof(inputFileComponent)); - - if (!files.Any()) - throw new ArgumentException("No files were provided to be uploaded.", nameof(files)); + ArgumentNullException.ThrowIfNull(inputFileComponent); + ArgumentNullException.ThrowIfNull(files); + ArgumentOutOfRangeException.ThrowIfZero(files.Length); var browserFiles = files.Select(file => new BUnitBrowserFile( file.Filename ?? string.Empty, @@ -38,4 +35,3 @@ public static void UploadFiles( } } } -#endif \ No newline at end of file diff --git a/src/bunit.web/Extensions/NodePrintExtensions.cs b/src/bunit.web/Extensions/NodePrintExtensions.cs index c54924824..b21f5eabf 100644 --- a/src/bunit.web/Extensions/NodePrintExtensions.cs +++ b/src/bunit.web/Extensions/NodePrintExtensions.cs @@ -20,8 +20,7 @@ public static class NodePrintExtensions /// The formatter to use. public static void ToHtml(this IEnumerable nodes, TextWriter writer, IMarkupFormatter formatter) { - if (nodes is null) - throw new ArgumentNullException(nameof(nodes)); + ArgumentNullException.ThrowIfNull(nodes); foreach (var node in nodes) { @@ -37,8 +36,7 @@ public static void ToHtml(this IEnumerable nodes, TextWriter writer, IMar /// public static string ToDiffMarkup(this IEnumerable nodes) { - if (nodes is null) - throw new ArgumentNullException(nameof(nodes)); + ArgumentNullException.ThrowIfNull(nodes); using var sw = new StringWriter(); nodes.ToHtml(sw, new DiffMarkupFormatter()); @@ -53,8 +51,7 @@ public static string ToDiffMarkup(this IEnumerable nodes) /// public static string ToDiffMarkup(this IMarkupFormattable markupFormattable) { - if (markupFormattable is null) - throw new ArgumentNullException(nameof(markupFormattable)); + ArgumentNullException.ThrowIfNull(markupFormattable); using var sw = new StringWriter(); markupFormattable.ToHtml(sw, new DiffMarkupFormatter()); @@ -67,8 +64,7 @@ public static string ToDiffMarkup(this IMarkupFormattable markupFormattable) /// public static string ToMarkup(this IEnumerable nodes) { - if (nodes is null) - throw new ArgumentNullException(nameof(nodes)); + ArgumentNullException.ThrowIfNull(nodes); using var sw = new StringWriter(); var formatter = new PrettyMarkupFormatter @@ -86,8 +82,7 @@ public static string ToMarkup(this IEnumerable nodes) /// public static string ToMarkup(this IMarkupFormattable markupFormattable) { - if (markupFormattable is null) - throw new ArgumentNullException(nameof(markupFormattable)); + ArgumentNullException.ThrowIfNull(markupFormattable); using var sw = new StringWriter(); var formatter = new PrettyMarkupFormatter @@ -106,8 +101,7 @@ public static string ToMarkup(this IMarkupFormattable markupFormattable) /// public static string ToMarkupElementOnly(this IElement element) { - if (element is null) - throw new ArgumentNullException(nameof(element)); + ArgumentNullException.ThrowIfNull(element); var result = new StringBuilder(); result.Append(Symbols.LessThan); diff --git a/src/bunit.web/Extensions/RenderedFragmentExtensions.cs b/src/bunit.web/Extensions/RenderedFragmentExtensions.cs index 7c0da6a25..af888b3f2 100644 --- a/src/bunit.web/Extensions/RenderedFragmentExtensions.cs +++ b/src/bunit.web/Extensions/RenderedFragmentExtensions.cs @@ -18,8 +18,7 @@ public static class RenderedFragmentExtensions /// The group of selectors to use. public static IElement Find(this IRenderedFragment renderedFragment, string cssSelector) { - if (renderedFragment is null) - throw new ArgumentNullException(nameof(renderedFragment)); + ArgumentNullException.ThrowIfNull(renderedFragment); var result = renderedFragment.Nodes.QuerySelector(cssSelector); @@ -40,8 +39,7 @@ public static IElement Find(this IRenderedFragment renderedFragment, string cssS /// An , that can be refreshed to execute the search again. public static IRefreshableElementCollection FindAll(this IRenderedFragment renderedFragment, string cssSelector, bool enableAutoRefresh = false) { - if (renderedFragment is null) - throw new ArgumentNullException(nameof(renderedFragment)); + ArgumentNullException.ThrowIfNull(renderedFragment); return new RefreshableElementCollection(renderedFragment, cssSelector) { EnableAutoRefresh = enableAutoRefresh }; } @@ -55,8 +53,7 @@ public static IRefreshableElementCollection FindAll(this IRenderedFrag public static IRenderedComponent FindComponent(this IRenderedFragment renderedFragment) where TComponent : IComponent { - if (renderedFragment is null) - throw new ArgumentNullException(nameof(renderedFragment)); + ArgumentNullException.ThrowIfNull(renderedFragment); var renderer = renderedFragment.Services.GetRequiredService().Renderer; return (IRenderedComponent)renderer.FindComponent(renderedFragment); @@ -71,8 +68,7 @@ public static IRenderedComponent FindComponent(this IRen public static IReadOnlyList> FindComponents(this IRenderedFragment renderedFragment) where TComponent : IComponent { - if (renderedFragment is null) - throw new ArgumentNullException(nameof(renderedFragment)); + ArgumentNullException.ThrowIfNull(renderedFragment); var renderer = renderedFragment.Services.GetRequiredService().Renderer; var components = renderer.FindComponents(renderedFragment); diff --git a/src/bunit.web/Extensions/StubComponentFactoryCollectionExtensions.cs b/src/bunit.web/Extensions/StubComponentFactoryCollectionExtensions.cs index 011c82464..6a17b8ec1 100644 --- a/src/bunit.web/Extensions/StubComponentFactoryCollectionExtensions.cs +++ b/src/bunit.web/Extensions/StubComponentFactoryCollectionExtensions.cs @@ -1,4 +1,3 @@ -#if NET5_0_OR_GREATER using Bunit.ComponentFactories; using Bunit.TestDoubles; @@ -19,8 +18,7 @@ public static class StubComponentFactoryCollectionExtensions /// A . public static ComponentFactoryCollection AddStub(this ComponentFactoryCollection factories) where TComponent : IComponent { - if (factories is null) - throw new ArgumentNullException(nameof(factories)); + ArgumentNullException.ThrowIfNull(factories); factories.Add(new StubComponentFactory(CreatePredicate(typeof(TComponent)), null)); @@ -53,8 +51,7 @@ public static ComponentFactoryCollection AddStub(this ComponentFacto /// A . public static ComponentFactoryCollection AddStub(this ComponentFactoryCollection factories, RenderFragment replacementFragment) where TComponent : IComponent { - if (factories is null) - throw new ArgumentNullException(nameof(factories)); + ArgumentNullException.ThrowIfNull(factories); factories.Add(new StubComponentFactory(CreatePredicate(typeof(TComponent)), replacementFragment)); @@ -95,10 +92,8 @@ public static ComponentFactoryCollection AddStub( RenderFragment> replacementTemplate) where TComponent : IComponent { - if (factories is null) - throw new ArgumentNullException(nameof(factories)); - if (replacementTemplate is null) - throw new ArgumentNullException(nameof(replacementTemplate)); + ArgumentNullException.ThrowIfNull(factories); + ArgumentNullException.ThrowIfNull(replacementTemplate); factories.Add(new StubComponentFactory(CreatePredicate(typeof(TComponent)), replacementTemplate)); @@ -153,13 +148,10 @@ public static ComponentFactoryCollection AddStub( Predicate componentTypePredicate, RenderFragment replacementFragment) { - if (factories is null) - throw new ArgumentNullException(nameof(factories)); - if (componentTypePredicate is null) - throw new ArgumentNullException(nameof(componentTypePredicate)); + ArgumentNullException.ThrowIfNull(factories); + ArgumentNullException.ThrowIfNull(componentTypePredicate); factories.Add(new StubComponentFactory(componentTypePredicate, replacementFragment)); return factories; } } -#endif diff --git a/src/bunit.web/Extensions/TestRendererExtensions.cs b/src/bunit.web/Extensions/TestRendererExtensions.cs index 14b4965c3..d1b6243a5 100644 --- a/src/bunit.web/Extensions/TestRendererExtensions.cs +++ b/src/bunit.web/Extensions/TestRendererExtensions.cs @@ -18,8 +18,7 @@ public static class TestRendererExtensions public static IRenderedComponent RenderComponent(this ITestRenderer renderer, params ComponentParameter[] parameters) where TComponent : IComponent { - if (renderer is null) - throw new ArgumentNullException(nameof(renderer)); + ArgumentNullException.ThrowIfNull(renderer); var resultBase = renderer.RenderComponent(new ComponentParameterCollection { parameters }); if (resultBase is IRenderedComponent result) @@ -38,10 +37,8 @@ public static IRenderedComponent RenderComponent(this IT public static IRenderedComponent RenderComponent(this ITestRenderer renderer, Action> parameterBuilder) where TComponent : IComponent { - if (renderer is null) - throw new ArgumentNullException(nameof(renderer)); - if (parameterBuilder is null) - throw new ArgumentNullException(nameof(parameterBuilder)); + ArgumentNullException.ThrowIfNull(renderer); + ArgumentNullException.ThrowIfNull(parameterBuilder); var builder = new ComponentParameterCollectionBuilder(parameterBuilder); var resultBase = renderer.RenderComponent(builder.Build()); diff --git a/src/bunit.web/Extensions/TestServiceProviderExtensions.cs b/src/bunit.web/Extensions/TestServiceProviderExtensions.cs index e23f5b002..c93faa0ec 100644 --- a/src/bunit.web/Extensions/TestServiceProviderExtensions.cs +++ b/src/bunit.web/Extensions/TestServiceProviderExtensions.cs @@ -19,12 +19,9 @@ public static class TestServiceProviderExtensions /// public static IServiceCollection AddDefaultTestContextServices(this IServiceCollection services, TestContextBase testContext, BunitJSInterop jsInterop) { - if (services is null) - throw new System.ArgumentNullException(nameof(services)); - if (testContext is null) - throw new System.ArgumentNullException(nameof(testContext)); - if (jsInterop is null) - throw new System.ArgumentNullException(nameof(jsInterop)); + ArgumentNullException.ThrowIfNull(services); + ArgumentNullException.ThrowIfNull(testContext); + ArgumentNullException.ThrowIfNull(jsInterop); // Placeholders and defaults for common Blazor services services.AddLogging(); @@ -45,11 +42,9 @@ public static IServiceCollection AddDefaultTestContextServices(this IServiceColl services.AddSingleton(); services.AddSingleton(s => s.GetRequiredService()); -#if NET8_0_OR_GREATER // bUnits fake ScrollToLocationHash services.AddSingleton(); services.AddSupplyValueFromQueryProvider(); -#endif // bUnit specific services services.AddSingleton(testContext); @@ -59,9 +54,7 @@ public static IServiceCollection AddDefaultTestContextServices(this IServiceColl services.AddMemoryCache(); -#if NET6_0_OR_GREATER services.AddSingleton(); -#endif return services; } } diff --git a/src/bunit.web/Extensions/WaitForHelpers/WaitForElementsHelper.cs b/src/bunit.web/Extensions/WaitForHelpers/WaitForElementsHelper.cs index bde317a68..179fdec55 100644 --- a/src/bunit.web/Extensions/WaitForHelpers/WaitForElementsHelper.cs +++ b/src/bunit.web/Extensions/WaitForHelpers/WaitForElementsHelper.cs @@ -1,4 +1,5 @@ using System.Globalization; +using System.Text; using AngleSharp.Dom; namespace Bunit.Extensions.WaitForHelpers; @@ -9,7 +10,7 @@ namespace Bunit.Extensions.WaitForHelpers; internal class WaitForElementsHelper : WaitForHelper> { internal const string TimeoutBeforeFoundMessage = "The CSS selector did not result in any matching element(s) before the timeout period passed."; - internal const string TimeoutBeforeFoundWithCountMessage = "The CSS selector did not result in exactly {0} matching element(s) before the timeout period passed."; + internal static readonly CompositeFormat TimeoutBeforeFoundWithCountMessage = CompositeFormat.Parse("The CSS selector did not result in exactly {0} matching element(s) before the timeout period passed."); private readonly int? matchElementCount; /// diff --git a/src/bunit.web/JSInterop/BunitJSInterop.cs b/src/bunit.web/JSInterop/BunitJSInterop.cs index 4c15f4a65..2dbaa9787 100644 --- a/src/bunit.web/JSInterop/BunitJSInterop.cs +++ b/src/bunit.web/JSInterop/BunitJSInterop.cs @@ -1,8 +1,5 @@ using Bunit.JSInterop; - -#if NET5_0_OR_GREATER using Bunit.JSInterop.InvocationHandlers.Implementation; -#endif namespace Bunit; @@ -37,12 +34,7 @@ public BunitJSInterop() { mode = JSRuntimeMode.Strict; JSRuntime = new BunitJSRuntime(this); -#if NET5_0_OR_GREATER - AddCustomNet5Handlers(); -#endif -#if NET6_0_OR_GREATER - AddCustomNet6Handlers(); -#endif + AddCustomHandlers(); } /// @@ -51,8 +43,7 @@ public BunitJSInterop() /// public void AddInvocationHandler(JSRuntimeInvocationHandlerBase handler) { - if (handler is null) - throw new ArgumentNullException(nameof(handler)); + ArgumentNullException.ThrowIfNull(handler); var resultType = typeof(TResult); @@ -129,24 +120,14 @@ internal virtual void RegisterInvocation(JSRuntimeInvocation invocation) return default; } -#if NET5_0_OR_GREATER - private void AddCustomNet5Handlers() + private void AddCustomHandlers() { AddInvocationHandler(new FocusAsyncInvocationHandler()); AddInvocationHandler(new VirtualizeJSRuntimeInvocationHandler()); AddInvocationHandler(new LooseModeJSObjectReferenceInvocationHandler(this)); AddInvocationHandler(new InputFileInvocationHandler()); - } -#endif - -#if NET6_0_OR_GREATER - private void AddCustomNet6Handlers() - { AddInvocationHandler(new FocusOnNavigateHandler()); -#if NET7_0_OR_GREATER AddInvocationHandler(new NavigationLockDisableNavigationPromptInvocationHandler()); AddInvocationHandler(new NavigationLockEnableNavigationPromptInvocationHandler()); -#endif } -#endif -} \ No newline at end of file +} diff --git a/src/bunit.web/JSInterop/BunitJSInteropSetupExtensions.cs b/src/bunit.web/JSInterop/BunitJSInteropSetupExtensions.cs index 1044d829b..7cc5059f6 100644 --- a/src/bunit.web/JSInterop/BunitJSInteropSetupExtensions.cs +++ b/src/bunit.web/JSInterop/BunitJSInteropSetupExtensions.cs @@ -16,12 +16,9 @@ public static partial class BunitJSInteropSetupExtensions /// A . public static JSRuntimeInvocationHandler Setup(this BunitJSInterop jsInterop, InvocationMatcher invocationMatcher, bool isCatchAllHandler = false) { - if (jsInterop is null) - throw new ArgumentNullException(nameof(jsInterop)); + ArgumentNullException.ThrowIfNull(jsInterop); -#if NET5_0_OR_GREATER EnsureResultNotIJSObjectReference(); -#endif var result = new JSRuntimeInvocationHandler(invocationMatcher, isCatchAllHandler); jsInterop.AddInvocationHandler(result); @@ -72,8 +69,7 @@ public static JSRuntimeInvocationHandler Setup(this BunitJSInt /// A . public static JSRuntimeInvocationHandler SetupVoid(this BunitJSInterop jsInterop, InvocationMatcher invocationMatcher, bool isCatchAllHandler = false) { - if (jsInterop is null) - throw new ArgumentNullException(nameof(jsInterop)); + ArgumentNullException.ThrowIfNull(jsInterop); var result = new JSRuntimeInvocationHandler(invocationMatcher, isCatchAllHandler); jsInterop.AddInvocationHandler(result); @@ -122,8 +118,7 @@ public static JSRuntimeInvocationHandler SetupVoid(this BunitJSInterop jsInterop /// Returns the or null if no one is found. public static JSRuntimeInvocationHandler? TryGetInvokeHandler(this BunitJSInterop jsInterop, string identifier, params object?[]? arguments) { - if (jsInterop is null) - throw new ArgumentNullException(nameof(jsInterop)); + ArgumentNullException.ThrowIfNull(jsInterop); return jsInterop.TryGetHandlerFor( new JSRuntimeInvocation( @@ -144,19 +139,13 @@ public static JSRuntimeInvocationHandler SetupVoid(this BunitJSInterop jsInterop /// Returns the or null if no one is found. public static JSRuntimeInvocationHandler? TryGetInvokeVoidHandler(this BunitJSInterop jsInterop, string identifier, params object?[]? arguments) { - if (jsInterop is null) - throw new ArgumentNullException(nameof(jsInterop)); + ArgumentNullException.ThrowIfNull(jsInterop); var invocation = new JSRuntimeInvocation(identifier, default, arguments, typeof(object), string.Empty); -#if !NET6_0_OR_GREATER - return jsInterop.TryGetHandlerFor(invocation, x => x.IsVoidResultHandler) as JSRuntimeInvocationHandler; -#else return jsInterop.TryGetHandlerFor(invocation, x => x.IsVoidResultHandler) as JSRuntimeInvocationHandler; -#endif } -#if NET5_0_OR_GREATER private static void EnsureResultNotIJSObjectReference() { const string UseSetupModuleErrorMessage = "Use one of the SetupModule() methods instead to set up an invocation handler that returns an IJSObjectReference."; @@ -169,5 +158,4 @@ private static void EnsureResultNotIJSObjectReference() if (resultType == typeof(Microsoft.JSInterop.Implementation.JSObjectReference)) throw new ArgumentException(UseSetupModuleErrorMessage); } -#endif } diff --git a/src/bunit.web/JSInterop/BunitJSInteropSetupExtensions.net5.cs b/src/bunit.web/JSInterop/BunitJSInteropSetupExtensions.net5.cs index 8487570b6..ebf393656 100644 --- a/src/bunit.web/JSInterop/BunitJSInteropSetupExtensions.net5.cs +++ b/src/bunit.web/JSInterop/BunitJSInteropSetupExtensions.net5.cs @@ -1,11 +1,4 @@ -#if NET5_0_OR_GREATER -using System; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using Bunit.JSInterop; -using Bunit.JSInterop.InvocationHandlers; using Bunit.JSInterop.InvocationHandlers.Implementation; -using Microsoft.JSInterop; namespace Bunit; @@ -33,10 +26,8 @@ public static partial class BunitJSInteropSetupExtensions /// A . public static BunitJSModuleInterop SetupModule(this BunitJSInterop jsInterop, InvocationMatcher invocationMatcher, bool isCatchAllHandler = false) { - if (jsInterop is null) - throw new ArgumentNullException(nameof(jsInterop)); - if (invocationMatcher is null) - throw new ArgumentNullException(nameof(invocationMatcher)); + ArgumentNullException.ThrowIfNull(jsInterop); + ArgumentNullException.ThrowIfNull(invocationMatcher); var result = new JSObjectReferenceInvocationHandler(jsInterop, invocationMatcher, isCatchAllHandler); jsInterop.AddInvocationHandler(result); @@ -131,8 +122,7 @@ public static BunitJSModuleInterop SetupModule(this BunitJSInterop jsInterop) /// A or null if no one is found. public static BunitJSModuleInterop? TryGetModuleJSInterop(this BunitJSInterop jsInterop, string identifier, params object?[]? arguments) { - if (jsInterop is null) - throw new ArgumentNullException(nameof(jsInterop)); + ArgumentNullException.ThrowIfNull(jsInterop); var invocation = new JSRuntimeInvocation(identifier, default, arguments, typeof(IJSObjectReference), "InvokeAsync"); @@ -141,4 +131,3 @@ public static BunitJSModuleInterop SetupModule(this BunitJSInterop jsInterop) return handler?.JSInterop; } } -#endif diff --git a/src/bunit.web/JSInterop/BunitJSModuleInterop.cs b/src/bunit.web/JSInterop/BunitJSModuleInterop.cs index ca5746844..292df5eeb 100644 --- a/src/bunit.web/JSInterop/BunitJSModuleInterop.cs +++ b/src/bunit.web/JSInterop/BunitJSModuleInterop.cs @@ -1,4 +1,3 @@ -#if NET5_0_OR_GREATER namespace Bunit; /// @@ -44,4 +43,3 @@ internal override void RegisterInvocation(JSRuntimeInvocation invocation) parent.RegisterInvocation(invocation); } } -#endif diff --git a/src/bunit.web/JSInterop/Implementation/BunitJSObjectReference.cs b/src/bunit.web/JSInterop/Implementation/BunitJSObjectReference.cs index 49ab896a1..aaaf19ede 100644 --- a/src/bunit.web/JSInterop/Implementation/BunitJSObjectReference.cs +++ b/src/bunit.web/JSInterop/Implementation/BunitJSObjectReference.cs @@ -1,10 +1,4 @@ -#if NET5_0_OR_GREATER -using System; -using System.Diagnostics.CodeAnalysis; -using System.Threading; -using System.Threading.Tasks; using Bunit.JSInterop.Implementation; -using Microsoft.JSInterop; namespace Bunit; @@ -58,4 +52,3 @@ public void Dispose() /// public ValueTask DisposeAsync() => ValueTask.CompletedTask; } -#endif diff --git a/src/bunit.web/JSInterop/Implementation/BunitJSRuntime.net5.cs b/src/bunit.web/JSInterop/Implementation/BunitJSRuntime.net5.cs index f2f466d58..1a3a8d649 100644 --- a/src/bunit.web/JSInterop/Implementation/BunitJSRuntime.net5.cs +++ b/src/bunit.web/JSInterop/Implementation/BunitJSRuntime.net5.cs @@ -1,7 +1,5 @@ -#if NET5_0_OR_GREATER && !NET9_0_OR_GREATER -using System; +#if !NET9_0_OR_GREATER using Bunit.JSInterop.Implementation; -using Microsoft.JSInterop; namespace Bunit.JSInterop; diff --git a/src/bunit.web/JSInterop/Implementation/JSRuntimeExtensions.cs b/src/bunit.web/JSInterop/Implementation/JSRuntimeExtensions.cs index e29a37330..2490e4bc6 100644 --- a/src/bunit.web/JSInterop/Implementation/JSRuntimeExtensions.cs +++ b/src/bunit.web/JSInterop/Implementation/JSRuntimeExtensions.cs @@ -85,27 +85,13 @@ internal static TResult HandleInvokeUnmarshalled(this Bunit .GetResult(); } -#if !NET6_0_OR_GREATER - private static string GetInvokeAsyncMethodName() - => typeof(TValue) == typeof(object) - ? "InvokeVoidAsync" - : "InvokeAsync"; -#else private static string GetInvokeAsyncMethodName() => typeof(TValue) == typeof(Microsoft.JSInterop.Infrastructure.IJSVoidResult) ? "InvokeVoidAsync" : "InvokeAsync"; -#endif -#if !NET6_0_OR_GREATER - private static string GetInvokeMethodName() - => typeof(TValue) == typeof(object) - ? "InvokeVoid" - : "Invoke"; -#else private static string GetInvokeMethodName() => typeof(TValue) == typeof(Microsoft.JSInterop.Infrastructure.IJSVoidResult) ? "InvokeVoid" : "Invoke"; -#endif } diff --git a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/FocusAsyncInvocationHandler.cs b/src/bunit.web/JSInterop/InvocationHandlers/Implementation/FocusAsyncInvocationHandler.cs index 1beae3348..26813499d 100644 --- a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/FocusAsyncInvocationHandler.cs +++ b/src/bunit.web/JSInterop/InvocationHandlers/Implementation/FocusAsyncInvocationHandler.cs @@ -1,8 +1,3 @@ - -#if NET5_0_OR_GREATER -using System; -using Microsoft.AspNetCore.Components; - namespace Bunit.JSInterop.InvocationHandlers.Implementation; /// @@ -26,4 +21,3 @@ internal FocusAsyncInvocationHandler() SetVoidResult(); } } -#endif diff --git a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/FocusOnNavigateHandler.cs b/src/bunit.web/JSInterop/InvocationHandlers/Implementation/FocusOnNavigateHandler.cs index 260326c0c..33795b8b7 100644 --- a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/FocusOnNavigateHandler.cs +++ b/src/bunit.web/JSInterop/InvocationHandlers/Implementation/FocusOnNavigateHandler.cs @@ -1,6 +1,3 @@ -#if NET6_0_OR_GREATER -using System; -using Microsoft.AspNetCore.Components; namespace Bunit.JSInterop.InvocationHandlers.Implementation; /// @@ -24,4 +21,3 @@ internal FocusOnNavigateHandler() SetVoidResult(); } } -#endif diff --git a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/InputFileInvocationHandler.cs b/src/bunit.web/JSInterop/InvocationHandlers/Implementation/InputFileInvocationHandler.cs index 85f0971a8..f2cd98cd8 100644 --- a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/InputFileInvocationHandler.cs +++ b/src/bunit.web/JSInterop/InvocationHandlers/Implementation/InputFileInvocationHandler.cs @@ -1,5 +1,4 @@ -#if NET5_0_OR_GREATER -namespace Bunit.JSInterop.InvocationHandlers.Implementation; +namespace Bunit.JSInterop.InvocationHandlers.Implementation; internal sealed class InputFileInvocationHandler : JSRuntimeInvocationHandler { @@ -11,4 +10,3 @@ internal InputFileInvocationHandler() SetVoidResult(); } } -#endif \ No newline at end of file diff --git a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/JSObjectReferenceInvocationHandler.cs b/src/bunit.web/JSInterop/InvocationHandlers/Implementation/JSObjectReferenceInvocationHandler.cs index b824ed9c5..83d0424c7 100644 --- a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/JSObjectReferenceInvocationHandler.cs +++ b/src/bunit.web/JSInterop/InvocationHandlers/Implementation/JSObjectReferenceInvocationHandler.cs @@ -1,5 +1,3 @@ -#if NET5_0_OR_GREATER - namespace Bunit.JSInterop.InvocationHandlers.Implementation; /// @@ -25,4 +23,3 @@ public JSObjectReferenceInvocationHandler(BunitJSInterop parent, InvocationMatch SetResult(new BunitJSObjectReference(JSInterop)); } } -#endif diff --git a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/LooseModeJSObjectReferenceInvocationHandler.cs b/src/bunit.web/JSInterop/InvocationHandlers/Implementation/LooseModeJSObjectReferenceInvocationHandler.cs index 356257b3a..7ff86b7fc 100644 --- a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/LooseModeJSObjectReferenceInvocationHandler.cs +++ b/src/bunit.web/JSInterop/InvocationHandlers/Implementation/LooseModeJSObjectReferenceInvocationHandler.cs @@ -1,5 +1,3 @@ -#if NET5_0_OR_GREATER - namespace Bunit.JSInterop.InvocationHandlers.Implementation; /// @@ -15,4 +13,3 @@ internal LooseModeJSObjectReferenceInvocationHandler(BunitJSInterop parent) SetResult(new BunitJSObjectReference(parent)); } } -#endif diff --git a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/NavigationLockDisableNavigationPromptInvocationHandler.cs b/src/bunit.web/JSInterop/InvocationHandlers/Implementation/NavigationLockDisableNavigationPromptInvocationHandler.cs index f1740d2ce..f80d3a60c 100644 --- a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/NavigationLockDisableNavigationPromptInvocationHandler.cs +++ b/src/bunit.web/JSInterop/InvocationHandlers/Implementation/NavigationLockDisableNavigationPromptInvocationHandler.cs @@ -1,4 +1,3 @@ -#if NET7_0_OR_GREATER namespace Bunit.JSInterop.InvocationHandlers.Implementation; internal sealed class NavigationLockDisableNavigationPromptInvocationHandler : JSRuntimeInvocationHandler @@ -11,4 +10,3 @@ internal NavigationLockDisableNavigationPromptInvocationHandler() SetVoidResult(); } } -#endif diff --git a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/NavigationLockEnableNavigationPromptInvocationHandler.cs b/src/bunit.web/JSInterop/InvocationHandlers/Implementation/NavigationLockEnableNavigationPromptInvocationHandler.cs index c5015288e..a4df314ec 100644 --- a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/NavigationLockEnableNavigationPromptInvocationHandler.cs +++ b/src/bunit.web/JSInterop/InvocationHandlers/Implementation/NavigationLockEnableNavigationPromptInvocationHandler.cs @@ -1,4 +1,3 @@ -#if NET7_0_OR_GREATER namespace Bunit.JSInterop.InvocationHandlers.Implementation; internal sealed class NavigationLockEnableNavigationPromptInvocationHandler : JSRuntimeInvocationHandler @@ -11,4 +10,3 @@ internal NavigationLockEnableNavigationPromptInvocationHandler() SetVoidResult(); } } -#endif diff --git a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/VirtualizeJSRuntimeInvocationHandler.cs b/src/bunit.web/JSInterop/InvocationHandlers/Implementation/VirtualizeJSRuntimeInvocationHandler.cs index 59c80ac56..97814aed3 100644 --- a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/VirtualizeJSRuntimeInvocationHandler.cs +++ b/src/bunit.web/JSInterop/InvocationHandlers/Implementation/VirtualizeJSRuntimeInvocationHandler.cs @@ -1,11 +1,6 @@ -#if NET5_0_OR_GREATER -using System; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.Reflection; -using System.Threading.Tasks; using Microsoft.AspNetCore.Components.Web.Virtualization; -using Microsoft.JSInterop; namespace Bunit.JSInterop.InvocationHandlers.Implementation { @@ -38,11 +33,7 @@ internal VirtualizeJSRuntimeInvocationHandler() { } /// -#if !NET6_0_OR_GREATER - protected internal override Task HandleAsync(JSRuntimeInvocation invocation) -#else protected internal override Task HandleAsync(JSRuntimeInvocation invocation) -#endif { if (!invocation.Identifier.Equals(JsFunctionsPrefix + "dispose", StringComparison.Ordinal)) { @@ -73,4 +64,3 @@ private static void InvokeOnSpacerBeforeVisible(object dotNetObjectReference) } } } -#endif diff --git a/src/bunit.web/JSInterop/InvocationHandlers/JSRuntimeInvocationHandler.cs b/src/bunit.web/JSInterop/InvocationHandlers/JSRuntimeInvocationHandler.cs index 2c7e0f888..7d2cc5a26 100644 --- a/src/bunit.web/JSInterop/InvocationHandlers/JSRuntimeInvocationHandler.cs +++ b/src/bunit.web/JSInterop/InvocationHandlers/JSRuntimeInvocationHandler.cs @@ -4,11 +4,7 @@ namespace Bunit; /// Represents a handler for an invocation of a JavaScript function which returns nothing, with specific arguments. /// public class JSRuntimeInvocationHandler -#if !NET6_0_OR_GREATER - : JSRuntimeInvocationHandlerBase -#else : JSRuntimeInvocationHandlerBase -#endif { /// public override sealed bool IsVoidResultHandler => true; diff --git a/src/bunit.web/JSInterop/JSRuntimeInvocation.cs b/src/bunit.web/JSInterop/JSRuntimeInvocation.cs index d30350a2d..ca7ea33c1 100644 --- a/src/bunit.web/JSInterop/JSRuntimeInvocation.cs +++ b/src/bunit.web/JSInterop/JSRuntimeInvocation.cs @@ -66,11 +66,7 @@ public JSRuntimeInvocation( Arguments = args ?? Array.Empty(); ResultType = resultType; InvocationMethodName = invocationMethodName; -#if !NET6_0_OR_GREATER - IsVoidResultInvocation = resultType == typeof(object); -#else IsVoidResultInvocation = resultType == typeof(Microsoft.JSInterop.Infrastructure.IJSVoidResult); -#endif } /// diff --git a/src/bunit.web/JSInterop/JSRuntimeUnhandledInvocationException.cs b/src/bunit.web/JSInterop/JSRuntimeUnhandledInvocationException.cs index 875d3a852..95fcc126f 100644 --- a/src/bunit.web/JSInterop/JSRuntimeUnhandledInvocationException.cs +++ b/src/bunit.web/JSInterop/JSRuntimeUnhandledInvocationException.cs @@ -118,18 +118,12 @@ private static string GetGenericInvocationArguments(JSRuntimeInvocation invocati } } -#if NET5_0_OR_GREATER private static bool IsImportModuleInvocation(JSRuntimeInvocation invocation) { const string DefaultImportIdentifier = "import"; return string.Equals(invocation.Identifier, DefaultImportIdentifier, StringComparison.Ordinal) && typeof(IJSObjectReference).IsAssignableFrom(invocation.ResultType); } -#else - [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Method to allow compatibility with netstandard2.1")] - private static bool IsImportModuleInvocation(JSRuntimeInvocation runtimeInvocation) - => false; -#endif private static string GetArguments(JSRuntimeInvocation invocation, bool includeIdentifier = true) { diff --git a/src/bunit.web/Rendering/BunitHtmlParser.cs b/src/bunit.web/Rendering/BunitHtmlParser.cs index f56c008b4..0551f71c8 100644 --- a/src/bunit.web/Rendering/BunitHtmlParser.cs +++ b/src/bunit.web/Rendering/BunitHtmlParser.cs @@ -20,7 +20,7 @@ public sealed class BunitHtmlParser : IDisposable private static readonly string[] SpecialHtmlElements = { "HTML", "HEAD", "BODY", "!DOCTYPE" }; private readonly IBrowsingContext context; - private readonly IHtmlParser htmlParser; + private readonly HtmlParser htmlParser; private readonly List documents = new(); /// @@ -59,8 +59,7 @@ private BunitHtmlParser(IConfiguration angleSharpConfiguration) /// The . public INodeList Parse([StringSyntax("Html")]string markup) { - if (markup is null) - throw new ArgumentNullException(nameof(markup)); + ArgumentNullException.ThrowIfNull(markup); var document = GetNewDocumentAsync().GetAwaiter().GetResult(); @@ -71,7 +70,7 @@ public INodeList Parse([StringSyntax("Html")]string markup) : htmlParser.ParseFragment(markup, ctx!); } - private INodeList ParseSpecial(string markup, string matchedElement) + private SingleNodeNodeList ParseSpecial(string markup, string matchedElement) { var doc = htmlParser.ParseDocument(markup); diff --git a/src/bunit.web/Rendering/Internal/Htmlizer.cs b/src/bunit.web/Rendering/Internal/Htmlizer.cs index 24c42b7c7..fc7811d98 100644 --- a/src/bunit.web/Rendering/Internal/Htmlizer.cs +++ b/src/bunit.web/Rendering/Internal/Htmlizer.cs @@ -41,10 +41,7 @@ internal static class Htmlizer public static bool IsBlazorAttribute(string attributeName) { - if (attributeName is null) - { - throw new ArgumentNullException(nameof(attributeName)); - } + ArgumentNullException.ThrowIfNull(attributeName); return attributeName.StartsWith(BlazorAttrPrefix, StringComparison.Ordinal) || attributeName.StartsWith(BlazorCssScopeAttrPrefix, StringComparison.Ordinal); diff --git a/src/bunit.web/Rendering/WebTestRenderer.cs b/src/bunit.web/Rendering/WebTestRenderer.cs index 0e710b50a..3a9a87a4b 100644 --- a/src/bunit.web/Rendering/WebTestRenderer.cs +++ b/src/bunit.web/Rendering/WebTestRenderer.cs @@ -1,11 +1,4 @@ -#if NET5_0_OR_GREATER -using Microsoft.AspNetCore.Components; -using Microsoft.Extensions.DependencyInjection; -#endif using Microsoft.Extensions.Logging; -#if NET5_0_OR_GREATER -using Microsoft.JSInterop; -#endif namespace Bunit.Rendering; @@ -21,12 +14,9 @@ public class WebTestRenderer : TestRenderer public WebTestRenderer(IRenderedComponentActivator renderedComponentActivator, TestServiceProvider services, ILoggerFactory loggerFactory) : base(renderedComponentActivator, services, loggerFactory) { -#if NET5_0_OR_GREATER ElementReferenceContext = new WebElementReferenceContext(services.GetRequiredService()); -#endif } -#if NET5_0_OR_GREATER /// /// Initializes a new instance of the class. /// @@ -35,5 +25,4 @@ public WebTestRenderer(IRenderedComponentActivator renderedComponentActivator, T { ElementReferenceContext = new WebElementReferenceContext(services.GetRequiredService()); } -#endif -} \ No newline at end of file +} diff --git a/src/bunit.web/TestContext.cs b/src/bunit.web/TestContext.cs index 315aa4ddf..a0ada8011 100644 --- a/src/bunit.web/TestContext.cs +++ b/src/bunit.web/TestContext.cs @@ -86,14 +86,10 @@ protected override ITestRenderer CreateTestRenderer() { var renderedComponentActivator = Services.GetRequiredService(); var logger = Services.GetRequiredService(); -#if !NET5_0_OR_GREATER - return new WebTestRenderer(renderedComponentActivator, Services, logger); -#else + var componentActivator = Services.GetService(); return componentActivator is null ? new WebTestRenderer(renderedComponentActivator, Services, logger) : new WebTestRenderer(renderedComponentActivator, Services, logger, componentActivator); -#endif - } } diff --git a/src/bunit.web/TestDoubles/Authorization/FakeAuthorizationExtensions.cs b/src/bunit.web/TestDoubles/Authorization/FakeAuthorizationExtensions.cs index 366c35a11..ed10641c4 100644 --- a/src/bunit.web/TestDoubles/Authorization/FakeAuthorizationExtensions.cs +++ b/src/bunit.web/TestDoubles/Authorization/FakeAuthorizationExtensions.cs @@ -16,8 +16,7 @@ public static class FakeAuthorizationExtensions /// public static TestAuthorizationContext AddTestAuthorization(this TestContextBase context) { - if (context is null) - throw new ArgumentNullException(nameof(context)); + ArgumentNullException.ThrowIfNull(context); context.RenderTree.TryAdd(); context.Services.AddSingleton(); diff --git a/src/bunit.web/TestDoubles/Authorization/FakeAuthorizationService.cs b/src/bunit.web/TestDoubles/Authorization/FakeAuthorizationService.cs index 474bb000a..928f697c5 100644 --- a/src/bunit.web/TestDoubles/Authorization/FakeAuthorizationService.cs +++ b/src/bunit.web/TestDoubles/Authorization/FakeAuthorizationService.cs @@ -61,8 +61,7 @@ public void SetRoles(IEnumerable roles) /// Result of authorize request. public Task AuthorizeAsync(ClaimsPrincipal user, object? resource, IEnumerable requirements) { - if (requirements is null) - throw new ArgumentNullException(nameof(requirements)); + ArgumentNullException.ThrowIfNull(requirements); AuthorizationResult result; diff --git a/src/bunit.web/TestDoubles/Components/CapturedParameterView{TComponent}.cs b/src/bunit.web/TestDoubles/Components/CapturedParameterView{TComponent}.cs index d10be16cc..6129730b3 100644 --- a/src/bunit.web/TestDoubles/Components/CapturedParameterView{TComponent}.cs +++ b/src/bunit.web/TestDoubles/Components/CapturedParameterView{TComponent}.cs @@ -1,4 +1,3 @@ -#if NET5_0_OR_GREATER using System.Collections; using System.Collections.Immutable; using System.Linq.Expressions; @@ -68,8 +67,7 @@ public bool TryGetValue(string key, [MaybeNullWhen(false)] out object value) /// The . public TValue Get(Expression> parameterSelector) { - if (parameterSelector is null) - throw new ArgumentNullException(nameof(parameterSelector)); + ArgumentNullException.ThrowIfNull(parameterSelector); if (parameterSelector.Body is not MemberExpression { Member: PropertyInfo propInfoCandidate }) throw new ArgumentException($"The parameter selector '{parameterSelector}' does not resolve to a public property on the component '{typeof(TComponent)}'.", nameof(parameterSelector)); @@ -108,4 +106,3 @@ IEnumerator IEnumerable.GetEnumerator() public static CapturedParameterView From(ParameterView parameters) => new(parameters.ToDictionary()!); } -#endif diff --git a/src/bunit.web/TestDoubles/Components/ComponentDoubleBase{TComponent}.cs b/src/bunit.web/TestDoubles/Components/ComponentDoubleBase{TComponent}.cs index 9cb924278..4595d2667 100644 --- a/src/bunit.web/TestDoubles/Components/ComponentDoubleBase{TComponent}.cs +++ b/src/bunit.web/TestDoubles/Components/ComponentDoubleBase{TComponent}.cs @@ -1,4 +1,3 @@ -#if NET5_0_OR_GREATER namespace Bunit.TestDoubles; /// @@ -41,4 +40,3 @@ protected virtual void BuildRenderTree(RenderTreeBuilder builder) { } [SuppressMessage("Design", "CA1033:Interface methods should be callable by child types", Justification = "This method is called by the Blazor runtime. Should not be called by inheriting types.")] void IComponent.Attach(RenderHandle renderHandle) => this.renderHandle = renderHandle; } -#endif diff --git a/src/bunit.web/TestDoubles/Components/ParameterNotFoundException.cs b/src/bunit.web/TestDoubles/Components/ParameterNotFoundException.cs index cb569b8b9..0782229b3 100644 --- a/src/bunit.web/TestDoubles/Components/ParameterNotFoundException.cs +++ b/src/bunit.web/TestDoubles/Components/ParameterNotFoundException.cs @@ -1,8 +1,7 @@ -#if NET5_0_OR_GREATER namespace Bunit.TestDoubles; /// -/// Represents an exception which is thrown when the +/// Represents an exception which is thrown when the /// /// is used to get a parameter that was not passed to the doubled component. /// @@ -22,4 +21,3 @@ private ParameterNotFoundException(SerializationInfo info, StreamingContext cont { } } -#endif diff --git a/src/bunit.web/TestDoubles/Components/Stub{TComponent}.cs b/src/bunit.web/TestDoubles/Components/Stub{TComponent}.cs index 78625eb33..9a1913218 100644 --- a/src/bunit.web/TestDoubles/Components/Stub{TComponent}.cs +++ b/src/bunit.web/TestDoubles/Components/Stub{TComponent}.cs @@ -1,4 +1,3 @@ -#if NET5_0_OR_GREATER using System.Diagnostics; namespace Bunit.TestDoubles; @@ -51,4 +50,3 @@ protected override void BuildRenderTree(RenderTreeBuilder builder) } } } -#endif diff --git a/src/bunit.web/TestDoubles/ErrorBoundary/BunitErrorBoundaryLogger.cs b/src/bunit.web/TestDoubles/ErrorBoundary/BunitErrorBoundaryLogger.cs index 8fd109bee..108e64718 100644 --- a/src/bunit.web/TestDoubles/ErrorBoundary/BunitErrorBoundaryLogger.cs +++ b/src/bunit.web/TestDoubles/ErrorBoundary/BunitErrorBoundaryLogger.cs @@ -1,4 +1,3 @@ -#if NET6_0_OR_GREATER using Microsoft.Extensions.Logging; namespace Bunit.TestDoubles; @@ -31,4 +30,3 @@ public ValueTask LogErrorAsync(Exception exception) return ValueTask.CompletedTask; } } -#endif diff --git a/src/bunit.web/TestDoubles/Localization/MissingMockStringLocalizationException.cs b/src/bunit.web/TestDoubles/Localization/MissingMockStringLocalizationException.cs index 4ce43d8b1..f6182cf52 100644 --- a/src/bunit.web/TestDoubles/Localization/MissingMockStringLocalizationException.cs +++ b/src/bunit.web/TestDoubles/Localization/MissingMockStringLocalizationException.cs @@ -27,19 +27,15 @@ public MissingMockStringLocalizationException(string methodName, params object?[ private MissingMockStringLocalizationException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { - if (serializationInfo is null) - throw new ArgumentNullException(nameof(serializationInfo)); + ArgumentNullException.ThrowIfNull(serializationInfo); Arguments = serializationInfo.GetValue(nameof(Arguments), Array.Empty().GetType()) as object?[] ?? Array.Empty(); } /// ¨ -#if NET8_0_OR_GREATER [Obsolete("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] -#endif public override void GetObjectData(SerializationInfo info, StreamingContext context) { - if (info is null) - throw new ArgumentNullException(nameof(info)); + ArgumentNullException.ThrowIfNull(info); info.AddValue(nameof(Arguments), Arguments, Array.Empty().GetType()); base.GetObjectData(info, context); } diff --git a/src/bunit.web/TestDoubles/NavigationManager/FakeNavigationManager.cs b/src/bunit.web/TestDoubles/NavigationManager/FakeNavigationManager.cs index 574807cf3..12c9e7bdb 100644 --- a/src/bunit.web/TestDoubles/NavigationManager/FakeNavigationManager.cs +++ b/src/bunit.web/TestDoubles/NavigationManager/FakeNavigationManager.cs @@ -33,42 +33,6 @@ public FakeNavigationManager(TestContextBase testContextBase) Initialize("http://localhost/", "http://localhost/"); } -#if !NET6_0_OR_GREATER - /// - protected override void NavigateToCore(string uri, bool forceLoad) - { - var absoluteUri = GetNewAbsoluteUri(uri); - var changedBaseUri = HasDifferentBaseUri(absoluteUri); - - if (changedBaseUri) - { - BaseUri = GetBaseUri(absoluteUri); - } - - Uri = ToAbsoluteUri(uri).OriginalString; - history.Push(new NavigationHistory(uri, new NavigationOptions(forceLoad))); - - testContextBase.Renderer.Dispatcher.InvokeAsync(() => - { - Uri = absoluteUri.OriginalString; - - // Only notify of changes if user navigates within the same - // base url (domain). Otherwise, the user navigated away - // from the app, and Blazor's NavigationManager would - // not notify of location changes. - if (!changedBaseUri) - { - NotifyLocationChanged(isInterceptedLink: false); - } - else - { - BaseUri = GetBaseUri(absoluteUri); - } - }); - } -#endif - -#if NET6_0_OR_GREATER /// protected override void NavigateToCore(string uri, NavigationOptions options) { @@ -85,16 +49,11 @@ protected override void NavigateToCore(string uri, NavigationOptions options) if (options.ReplaceHistoryEntry && history.Count > 0) history.Pop(); -#if NET7_0_OR_GREATER HistoryEntryState = options.ForceLoad ? null : options.HistoryEntryState; testContextBase.Renderer.Dispatcher.InvokeAsync(async () => -#else - testContextBase.Renderer.Dispatcher.InvokeAsync(() => -#endif { Uri = absoluteUri.OriginalString; -#if NET7_0_OR_GREATER var shouldContinueNavigation = false; try { @@ -112,10 +71,6 @@ protected override void NavigateToCore(string uri, NavigationOptions options) { return; } -#else - history.Push(new NavigationHistory(uri, options)); -#endif - // Only notify of changes if user navigates within the same // base url (domain). Otherwise, the user navigated away @@ -131,16 +86,13 @@ protected override void NavigateToCore(string uri, NavigationOptions options) } }); } -#endif -#if NET7_0_OR_GREATER /// protected override void SetNavigationLockState(bool value) {} /// protected override void HandleLocationChangingHandlerException(Exception ex, LocationChangingContext context) => throw ex; -#endif private URI GetNewAbsoluteUri(string uri) => new URI(uri, UriKind.RelativeOrAbsolute).IsAbsoluteUri diff --git a/src/bunit.web/TestDoubles/NavigationManager/NavigationHistory.cs b/src/bunit.web/TestDoubles/NavigationManager/NavigationHistory.cs index 9422f7a58..513cfddfc 100644 --- a/src/bunit.web/TestDoubles/NavigationManager/NavigationHistory.cs +++ b/src/bunit.web/TestDoubles/NavigationManager/NavigationHistory.cs @@ -1,15 +1,13 @@ -#if NET7_0_OR_GREATER using System.Text.Json; using Microsoft.AspNetCore.Components.Routing; using Microsoft.AspNetCore.Components.WebAssembly.Authentication; -#endif namespace Bunit.TestDoubles; /// /// Represents a navigation to a with a set of specific navigation . /// -public sealed class NavigationHistory : IEquatable +public sealed record NavigationHistory { /// /// Gets the that was navigated to. @@ -20,14 +18,8 @@ public sealed class NavigationHistory : IEquatable /// /// Gets the options that was specified when the was navigated to. /// -#if !NET6_0_OR_GREATER - public Bunit.TestDoubles.NavigationOptions Options { get; } -#endif -#if NET6_0_OR_GREATER public NavigationOptions Options { get; } -#endif -#if NET7_0_OR_GREATER /// /// Gets the associated with this history entry. /// @@ -40,36 +32,7 @@ public sealed class NavigationHistory : IEquatable /// Will not be null when is . /// public Exception? Exception { get; } -#endif -#if !NET6_0_OR_GREATER - /// - /// Initializes a new instance of the class. - /// - /// - /// - [SuppressMessage("Design", "CA1054:URI-like parameters should not be strings", Justification = "Using string to align with NavigationManager")] - public NavigationHistory([StringSyntax(StringSyntaxAttribute.Uri)]string uri, Bunit.TestDoubles.NavigationOptions options) - { - Uri = uri; - Options = options; - } -#endif -#if NET6_0 - /// - /// Initializes a new instance of the class. - /// - /// - /// - [SuppressMessage("Design", "CA1054:URI-like parameters should not be strings", Justification = "Using string to align with NavigationManager")] - public NavigationHistory([StringSyntax(StringSyntaxAttribute.Uri)]string uri, NavigationOptions options) - { - Uri = uri; - Options = options; - } -#endif - -#if NET7_0_OR_GREATER /// /// Initializes a new instance of the class. /// @@ -109,32 +72,6 @@ public NavigationHistory( Options.HistoryEntryState, options ?? JsonSerializerOptions.Default); } -#endif - - /// -#if !NET6_0_OR_GREATER - public bool Equals(NavigationHistory? other) - => other is not null && string.Equals(Uri, other.Uri, StringComparison.Ordinal) && Options.Equals(other.Options); -#endif -#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); /// public override int GetHashCode() => HashCode.Combine(Uri, Options); diff --git a/src/bunit.web/TestDoubles/NavigationManager/NavigationOptions.cs b/src/bunit.web/TestDoubles/NavigationManager/NavigationOptions.cs deleted file mode 100644 index 4a6ddad2e..000000000 --- a/src/bunit.web/TestDoubles/NavigationManager/NavigationOptions.cs +++ /dev/null @@ -1,32 +0,0 @@ -#if !NET6_0_OR_GREATER -namespace Bunit.TestDoubles; - -/// -/// Additional options for navigating to another URI. -/// -public sealed class NavigationOptions : IEquatable -{ - /// - /// If true, bypasses client-side routing and forces the browser to load the new - /// page from the server, whether or not the URI would normally be handled by the - /// client-side router. - /// - public bool ForceLoad { get; } - - /// - /// Initializes a new instance of the class. - /// - public NavigationOptions(bool forceLoad) => ForceLoad = forceLoad; - - /// - public bool Equals(NavigationOptions? other) - => other is not null && ForceLoad == other.ForceLoad; - - /// - public override bool Equals(object? obj) - => obj is NavigationOptions other && Equals(other); - - /// - public override int GetHashCode() => ForceLoad.GetHashCode(); -} -#endif diff --git a/src/bunit.web/TestDoubles/NavigationManager/NavigationState.cs b/src/bunit.web/TestDoubles/NavigationManager/NavigationState.cs index 4f11ecb44..ea5b6976d 100644 --- a/src/bunit.web/TestDoubles/NavigationManager/NavigationState.cs +++ b/src/bunit.web/TestDoubles/NavigationManager/NavigationState.cs @@ -1,4 +1,3 @@ -#if NET7_0_OR_GREATER namespace Bunit.TestDoubles; /// @@ -21,4 +20,3 @@ public enum NavigationState /// Faulted } -#endif diff --git a/src/bunit.web/TestDoubles/ScrollToLocationHash/BunitScrollToLocationHash.cs b/src/bunit.web/TestDoubles/ScrollToLocationHash/BunitScrollToLocationHash.cs index 0db5ba9f0..40b2e9df9 100644 --- a/src/bunit.web/TestDoubles/ScrollToLocationHash/BunitScrollToLocationHash.cs +++ b/src/bunit.web/TestDoubles/ScrollToLocationHash/BunitScrollToLocationHash.cs @@ -1,4 +1,3 @@ -#if NET8_0_OR_GREATER using Microsoft.AspNetCore.Components.Routing; namespace Bunit.TestDoubles; @@ -7,4 +6,3 @@ internal sealed class BunitScrollToLocationHash : IScrollToLocationHash { public Task RefreshScrollPositionForHash(string locationAbsolute) => Task.CompletedTask; } -#endif \ No newline at end of file diff --git a/src/bunit.web/bunit.web.csproj b/src/bunit.web/bunit.web.csproj index 9b453fc70..43a24a9cf 100644 --- a/src/bunit.web/bunit.web.csproj +++ b/src/bunit.web/bunit.web.csproj @@ -1,7 +1,7 @@ - netstandard2.1;net5.0;net6.0;net7.0;net8.0;net9.0 + net8.0;net9.0 Bunit Bunit.Web - + true @@ -52,7 +52,7 @@ + Condition="$(MSBuildProjectName) != 'bunit.template' AND $(MSBuildProjectName) != 'AngleSharpWrappers.Tests'"> diff --git a/MIGRATION.md b/MIGRATION.md index e47004cd5..142d55daa 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -21,4 +21,7 @@ public static class Extensions return loggerFactory.CreateLogger(); } } -``` \ No newline at end of file +``` + +## Merge of `bunit.core` and `bunit.web` +The `bunit.core` and `bunit.web` packages have been merged into a single `bunit` package. If you used either of these packages, you should remove them and install the `bunit` package instead. diff --git a/README.md b/README.md index a1f0bb490..ff3bbd61f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![GitHub tag](https://img.shields.io/github/v/tag/bUnit-dev/bUnit?include_prereleases&logo=github&style=flat-square)](https://github.com/bUnit-dev/bUnit/releases) -[![Nuget](https://img.shields.io/nuget/dt/bunit.core?logo=nuget&style=flat-square)](https://www.nuget.org/packages/bunit/) +[![Nuget](https://img.shields.io/nuget/dt/bunit?logo=nuget&style=flat-square)](https://www.nuget.org/packages/bunit/) [![Issues Open](https://img.shields.io/github/issues/bUnit-dev/bUnit.svg?style=flat-square&logo=github)](https://github.com/bUnit-dev/bUnit/issues) # bUnit - a testing library for Blazor components @@ -29,9 +29,7 @@ bUnit is available on NuGet in various incarnations. Most should just pick the [ | Name | Description | NuGet Download Link | | ----- | ----- | ---- | -| [bUnit](https://www.nuget.org/packages/bunit/) | Includes the bUnit.core and bUnit.web packages. | [![Nuget](https://img.shields.io/nuget/dt/bunit?logo=nuget&style=flat-square)](https://www.nuget.org/packages/bunit/) | -| [bUnit.core](https://www.nuget.org/packages/bunit.core/) | Core library that enables rendering a Blazor component in a test context. | [![Nuget](https://img.shields.io/nuget/dt/bunit.core?logo=nuget&style=flat-square)](https://www.nuget.org/packages/bunit.core/) | -| [bUnit.web](https://www.nuget.org/packages/bunit.web/) | Adds support for testing Blazor components for the web. This includes bUnit.core. | [![Nuget](https://img.shields.io/nuget/dt/bunit.web?logo=nuget&style=flat-square)](https://www.nuget.org/packages/bunit.web/) | +| [bUnit](https://www.nuget.org/packages/bunit/) | Adds support for testing Blazor components. | [![Nuget](https://img.shields.io/nuget/dt/bunit?logo=nuget&style=flat-square)](https://www.nuget.org/packages/bunit/) | | [bUnit.template](https://www.nuget.org/packages/bunit.template/) | Template, which currently creates xUnit-based bUnit test projects only. | [![Nuget](https://img.shields.io/nuget/dt/bunit.template?logo=nuget&style=flat-square)](https://www.nuget.org/packages/bunit.template/) | | [bUnit.generators](https://www.nuget.org/packages/bunit.generators/)|Source code generators to minimize code setup in various situations.|[![Nuget](https://img.shields.io/nuget/dt/bunit.generators?logo=nuget&style=flat-square)](https://www.nuget.org/packages/bunit.generators/)| | [bUnit.web.query](https://www.nuget.org/packages/bunit.web.query/)|bUnit implementation of testing-library.com's query APIs.|[![Nuget](https://img.shields.io/nuget/dt/bunit.web.query?logo=nuget&style=flat-square)](https://www.nuget.org/packages/bunit.web.query/)| diff --git a/benchmark/Directory.Build.props b/benchmark/Directory.Build.props deleted file mode 100644 index 62cb9cc94..000000000 --- a/benchmark/Directory.Build.props +++ /dev/null @@ -1,14 +0,0 @@ - - - - enable - 10.0 - enable - CA1014,NU5104 - false - - - full - true - - diff --git a/benchmark/bunit.benchmarks.assets/Counter.razor b/benchmark/bunit.benchmarks.assets/Counter.razor deleted file mode 100644 index 381411d2a..000000000 --- a/benchmark/bunit.benchmarks.assets/Counter.razor +++ /dev/null @@ -1,21 +0,0 @@ -@page "/counter" - -

Counter - Example

- -

This is not the real counter example but a bit adopted to have more stuff in it.

-
- Look mum I am centered -
- -

Current count: @currentCount

- - - -@code { - private int currentCount = 0; - - private void IncrementCount() - { - currentCount++; - } -} \ No newline at end of file diff --git a/benchmark/bunit.benchmarks.assets/bunit.benchmarks.assets.csproj b/benchmark/bunit.benchmarks.assets/bunit.benchmarks.assets.csproj deleted file mode 100644 index d847c3ba1..000000000 --- a/benchmark/bunit.benchmarks.assets/bunit.benchmarks.assets.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - - - diff --git a/benchmark/bunit.benchmarks/Benchmark.cs b/benchmark/bunit.benchmarks/Benchmark.cs deleted file mode 100644 index 343f305fa..000000000 --- a/benchmark/bunit.benchmarks/Benchmark.cs +++ /dev/null @@ -1,14 +0,0 @@ -using BenchmarkDotNet.Attributes; -using bunit.benchmarks.assets; - -namespace Bunit; - -[MemoryDiagnoser] -public class Benchmark : BenchmarkBase -{ - [Benchmark] - public IRenderedComponentBase RenderCounter() - { - return RenderComponent(); - } -} \ No newline at end of file diff --git a/benchmark/bunit.benchmarks/BenchmarkBase.cs b/benchmark/bunit.benchmarks/BenchmarkBase.cs deleted file mode 100644 index f45d26972..000000000 --- a/benchmark/bunit.benchmarks/BenchmarkBase.cs +++ /dev/null @@ -1,47 +0,0 @@ -using BenchmarkDotNet.Attributes; -using Bunit.Rendering; -using Microsoft.AspNetCore.Components; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging.Abstractions; - -namespace Bunit; - -public abstract class BenchmarkBase -{ - private static readonly ComponentParameterCollection EmptyParameter = new(); - private readonly ServiceCollection services = new(); - - protected TestRenderer Renderer { get; private set; } = default!; - - [GlobalSetup] - public void Setup() - { - RegisterServices(services); - - var serviceProvider = services.BuildServiceProvider(); - Renderer = new TestRenderer( - new RenderedComponentActivator(serviceProvider), - new TestServiceProvider(services), - new NullLoggerFactory()); - } - - [GlobalCleanup] - public void Cleanup() - { - InternalCleanup(); - Renderer.Dispose(); - } - - protected IRenderedComponentBase RenderComponent() - where TComponent : IComponent => - Renderer.RenderComponent(EmptyParameter); - - protected virtual void InternalCleanup() - { - } - - protected virtual void RegisterServices(IServiceCollection serviceCollection) - { - services.AddSingleton(); - } -} \ No newline at end of file diff --git a/benchmark/bunit.benchmarks/Program.cs b/benchmark/bunit.benchmarks/Program.cs deleted file mode 100644 index 18d11e89b..000000000 --- a/benchmark/bunit.benchmarks/Program.cs +++ /dev/null @@ -1,6 +0,0 @@ -// See https://aka.ms/new-console-template for more information - -using BenchmarkDotNet.Running; -using Bunit; - -BenchmarkSwitcher.FromAssembly(typeof(Benchmark).Assembly).RunAll(); diff --git a/benchmark/bunit.benchmarks/bunit.benchmarks.csproj b/benchmark/bunit.benchmarks/bunit.benchmarks.csproj deleted file mode 100644 index 1212e538f..000000000 --- a/benchmark/bunit.benchmarks/bunit.benchmarks.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - Exe - net8.0 - enable - false - - - - - - - - - - - - - diff --git a/bunit.sln b/bunit.sln index c39a1c1ba..117ccb6ea 100644 --- a/bunit.sln +++ b/bunit.sln @@ -31,20 +31,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".text", ".text", "{392FCD4E ProjectSection(SolutionItems) = preProject CHANGELOG.md = CHANGELOG.md README.md = README.md + MIGRATION.md = MIGRATION.md EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit.core.tests", "tests\bunit.core.tests\bunit.core.tests.csproj", "{3A1486BF-1029-4E5B-A79B-2D36C8152240}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit", "src\bunit\bunit.csproj", "{1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit.core", "src\bunit.core\bunit.core.csproj", "{0C51D12D-A562-4229-B653-78B14960345C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit.web", "src\bunit.web\bunit.web.csproj", "{C91AE830-FFB5-49A9-A604-3F68B44EBCDC}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit.template", "src\bunit.template\bunit.template.csproj", "{6127D121-9387-451B-B15D-8350A32D3001}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit.web.tests", "tests\bunit.web.tests\bunit.web.tests.csproj", "{FC122F63-8B22-4BAE-B96A-7AF3194CD204}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit.testassets", "tests\bunit.testassets\bunit.testassets.csproj", "{7972A80F-30DC-4EF4-9294-7D4DD2965882}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".workflows", ".workflows", "{3B2F3419-5336-4147-A212-E19091195203}" @@ -55,15 +48,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".workflows", ".workflows", .github\workflows\release.yml = .github\workflows\release.yml EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmark", "benchmark", "{F6084D31-2A92-4794-A47E-A8F2254E6970}" - ProjectSection(SolutionItems) = preProject - benchmark\Directory.Build.props = benchmark\Directory.Build.props - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit.benchmarks", "benchmark\bunit.benchmarks\bunit.benchmarks.csproj", "{9F7A0623-8294-4A5D-946F-70C481732AA5}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit.benchmarks.assets", "benchmark\bunit.benchmarks.assets\bunit.benchmarks.assets.csproj", "{3619481F-DF6F-4399-9FED-450EE545A19E}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit.web.query", "src\bunit.web.query\bunit.web.query.csproj", "{0FF92169-7D8F-46A2-8327-A2F028CB426F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit.web.query.tests", "tests\bunit.web.query.tests\bunit.web.query.tests.csproj", "{DE975A0C-0672-4248-913E-D267C1001801}" @@ -74,44 +58,23 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit.generators.tests", "t EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit.generators", "src\bunit.generators\bunit.generators.csproj", "{A7C6A2AA-FF8F-4ED1-8590-5324FC566059}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bunit.tests", "tests\bunit.tests\bunit.tests.csproj", "{56889DE7-5E66-4E9C-815B-CBCFC9961612}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {3A1486BF-1029-4E5B-A79B-2D36C8152240}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3A1486BF-1029-4E5B-A79B-2D36C8152240}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3A1486BF-1029-4E5B-A79B-2D36C8152240}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3A1486BF-1029-4E5B-A79B-2D36C8152240}.Release|Any CPU.Build.0 = Release|Any CPU {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0C51D12D-A562-4229-B653-78B14960345C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0C51D12D-A562-4229-B653-78B14960345C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0C51D12D-A562-4229-B653-78B14960345C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0C51D12D-A562-4229-B653-78B14960345C}.Release|Any CPU.Build.0 = Release|Any CPU - {C91AE830-FFB5-49A9-A604-3F68B44EBCDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C91AE830-FFB5-49A9-A604-3F68B44EBCDC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C91AE830-FFB5-49A9-A604-3F68B44EBCDC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C91AE830-FFB5-49A9-A604-3F68B44EBCDC}.Release|Any CPU.Build.0 = Release|Any CPU + {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Release|Any CPU.Build.0 = Release|Any CPU {6127D121-9387-451B-B15D-8350A32D3001}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6127D121-9387-451B-B15D-8350A32D3001}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FC122F63-8B22-4BAE-B96A-7AF3194CD204}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FC122F63-8B22-4BAE-B96A-7AF3194CD204}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FC122F63-8B22-4BAE-B96A-7AF3194CD204}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FC122F63-8B22-4BAE-B96A-7AF3194CD204}.Release|Any CPU.Build.0 = Release|Any CPU {7972A80F-30DC-4EF4-9294-7D4DD2965882}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7972A80F-30DC-4EF4-9294-7D4DD2965882}.Debug|Any CPU.Build.0 = Debug|Any CPU {7972A80F-30DC-4EF4-9294-7D4DD2965882}.Release|Any CPU.ActiveCfg = Release|Any CPU {7972A80F-30DC-4EF4-9294-7D4DD2965882}.Release|Any CPU.Build.0 = Release|Any CPU - {9F7A0623-8294-4A5D-946F-70C481732AA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9F7A0623-8294-4A5D-946F-70C481732AA5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9F7A0623-8294-4A5D-946F-70C481732AA5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9F7A0623-8294-4A5D-946F-70C481732AA5}.Release|Any CPU.Build.0 = Release|Any CPU - {3619481F-DF6F-4399-9FED-450EE545A19E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3619481F-DF6F-4399-9FED-450EE545A19E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3619481F-DF6F-4399-9FED-450EE545A19E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3619481F-DF6F-4399-9FED-450EE545A19E}.Release|Any CPU.Build.0 = Release|Any CPU {0FF92169-7D8F-46A2-8327-A2F028CB426F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0FF92169-7D8F-46A2-8327-A2F028CB426F}.Debug|Any CPU.Build.0 = Debug|Any CPU {0FF92169-7D8F-46A2-8327-A2F028CB426F}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -132,25 +95,24 @@ Global {A7C6A2AA-FF8F-4ED1-8590-5324FC566059}.Debug|Any CPU.Build.0 = Debug|Any CPU {A7C6A2AA-FF8F-4ED1-8590-5324FC566059}.Release|Any CPU.ActiveCfg = Release|Any CPU {A7C6A2AA-FF8F-4ED1-8590-5324FC566059}.Release|Any CPU.Build.0 = Release|Any CPU + {56889DE7-5E66-4E9C-815B-CBCFC9961612}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {56889DE7-5E66-4E9C-815B-CBCFC9961612}.Debug|Any CPU.Build.0 = Debug|Any CPU + {56889DE7-5E66-4E9C-815B-CBCFC9961612}.Release|Any CPU.ActiveCfg = Release|Any CPU + {56889DE7-5E66-4E9C-815B-CBCFC9961612}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {3A1486BF-1029-4E5B-A79B-2D36C8152240} = {6EA09ED4-B714-4E6F-B0E1-4D987F8AE520} {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA} = {9A2B3B34-D41C-43E8-BC7D-246BEBE48D59} - {0C51D12D-A562-4229-B653-78B14960345C} = {9A2B3B34-D41C-43E8-BC7D-246BEBE48D59} - {C91AE830-FFB5-49A9-A604-3F68B44EBCDC} = {9A2B3B34-D41C-43E8-BC7D-246BEBE48D59} {6127D121-9387-451B-B15D-8350A32D3001} = {9A2B3B34-D41C-43E8-BC7D-246BEBE48D59} - {FC122F63-8B22-4BAE-B96A-7AF3194CD204} = {6EA09ED4-B714-4E6F-B0E1-4D987F8AE520} {7972A80F-30DC-4EF4-9294-7D4DD2965882} = {6EA09ED4-B714-4E6F-B0E1-4D987F8AE520} - {9F7A0623-8294-4A5D-946F-70C481732AA5} = {F6084D31-2A92-4794-A47E-A8F2254E6970} - {3619481F-DF6F-4399-9FED-450EE545A19E} = {F6084D31-2A92-4794-A47E-A8F2254E6970} {0FF92169-7D8F-46A2-8327-A2F028CB426F} = {9A2B3B34-D41C-43E8-BC7D-246BEBE48D59} {DE975A0C-0672-4248-913E-D267C1001801} = {6EA09ED4-B714-4E6F-B0E1-4D987F8AE520} {AE3DFB52-2BF4-4806-AD82-7FB7B38AC17F} = {9A2B3B34-D41C-43E8-BC7D-246BEBE48D59} {09046981-D9EC-4295-8502-721AC54E1F12} = {6EA09ED4-B714-4E6F-B0E1-4D987F8AE520} {A7C6A2AA-FF8F-4ED1-8590-5324FC566059} = {9A2B3B34-D41C-43E8-BC7D-246BEBE48D59} + {56889DE7-5E66-4E9C-815B-CBCFC9961612} = {6EA09ED4-B714-4E6F-B0E1-4D987F8AE520} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {24106918-1C86-4769-BDA6-9C80E64CD260} diff --git a/docs/samples/tests/mstest/bunit.docs.mstest.samples.csproj b/docs/samples/tests/mstest/bunit.docs.mstest.samples.csproj index 2d6428b0b..4bfdc389b 100644 --- a/docs/samples/tests/mstest/bunit.docs.mstest.samples.csproj +++ b/docs/samples/tests/mstest/bunit.docs.mstest.samples.csproj @@ -14,7 +14,7 @@
- + diff --git a/docs/samples/tests/nunit/bunit.docs.nunit.samples.csproj b/docs/samples/tests/nunit/bunit.docs.nunit.samples.csproj index a51a9ff84..0cd6ceefd 100644 --- a/docs/samples/tests/nunit/bunit.docs.nunit.samples.csproj +++ b/docs/samples/tests/nunit/bunit.docs.nunit.samples.csproj @@ -13,7 +13,7 @@ - + diff --git a/docs/samples/tests/razor/bunit.docs.razor.samples.csproj b/docs/samples/tests/razor/bunit.docs.razor.samples.csproj index 601c8a4c3..be87dd348 100644 --- a/docs/samples/tests/razor/bunit.docs.razor.samples.csproj +++ b/docs/samples/tests/razor/bunit.docs.razor.samples.csproj @@ -19,7 +19,7 @@ - + diff --git a/docs/samples/tests/xunit/bunit.docs.xunit.samples.csproj b/docs/samples/tests/xunit/bunit.docs.xunit.samples.csproj index be96270c2..5b1ce1458 100644 --- a/docs/samples/tests/xunit/bunit.docs.xunit.samples.csproj +++ b/docs/samples/tests/xunit/bunit.docs.xunit.samples.csproj @@ -21,7 +21,7 @@ - + diff --git a/src/bunit.core/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.cs b/src/bunit.core/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.cs deleted file mode 100644 index 00a2ce7d2..000000000 --- a/src/bunit.core/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System.Runtime.ExceptionServices; -using Bunit.Asserting; -using Bunit.Extensions.WaitForHelpers; - -namespace Bunit; - -/// -/// Helper methods dealing with async rendering during testing. -/// -public static class RenderedFragmentWaitForHelperExtensions -{ - /// - /// Wait until the provided action returns true, - /// or the is reached (default is one second). - /// - /// The is evaluated initially, and then each time - /// the renders. - /// - /// The render fragment or component to attempt to verify state against. - /// The predicate to invoke after each render, which must returns true when the desired state has been reached. - /// The maximum time to wait for the desired state. - /// Thrown if the throw an exception during invocation, or if the timeout has been reached. See the inner exception for details. - /// - /// If a debugger is attached the timeout is set to , giving the possibility to debug without the timeout triggering. - /// - public static void WaitForState(this IRenderedFragmentBase renderedFragment, Func statePredicate, TimeSpan? timeout = null) - { - using var waiter = new WaitForStateHelper(renderedFragment, statePredicate, timeout); - - try - { - waiter.WaitTask.GetAwaiter().GetResult(); - } - catch (AggregateException e) when (e.InnerExceptions.Count == 1) - { - ExceptionDispatchInfo.Capture(e.InnerExceptions[0]).Throw(); - } - } - - /// - /// Wait until the provided action returns true, - /// or the is reached (default is one second). - /// - /// The is evaluated initially, and then each time - /// the renders. - /// - /// The render fragment or component to attempt to verify state against. - /// The predicate to invoke after each render, which must returns true when the desired state has been reached. - /// The maximum time to wait for the desired state. - /// Thrown if the throw an exception during invocation, or if the timeout has been reached. See the inner exception for details. - internal static async Task WaitForStateAsync(this IRenderedFragmentBase renderedFragment, Func statePredicate, TimeSpan? timeout = null) - { - using var waiter = new WaitForStateHelper(renderedFragment, statePredicate, timeout); - - await waiter.WaitTask; - } - - /// - /// Wait until the provided passes (i.e. does not throw an - /// exception), or the is reached (default is one second). - /// - /// The is attempted initially, and then each time the renders. - /// - /// The rendered fragment to wait for renders from and assert against. - /// The verification or assertion to perform. - /// The maximum time to attempt the verification. - /// Thrown if the timeout has been reached. See the inner exception to see the captured assertion exception. - [AssertionMethod] - public static void WaitForAssertion(this IRenderedFragmentBase renderedFragment, Action assertion, TimeSpan? timeout = null) - { - using var waiter = new WaitForAssertionHelper(renderedFragment, assertion, timeout); - - try - { - waiter.WaitTask.GetAwaiter().GetResult(); - } - catch (AggregateException e) when (e.InnerExceptions.Count == 1) - { - ExceptionDispatchInfo.Capture(e.InnerExceptions[0]).Throw(); - } - } - - /// - /// Wait until the provided passes (i.e. does not throw an - /// exception), or the is reached (default is one second). - /// - /// The is attempted initially, and then each time the renders. - /// - /// The rendered fragment to wait for renders from and assert against. - /// The verification or assertion to perform. - /// The maximum time to attempt the verification. - /// Thrown if the timeout has been reached. See the inner exception to see the captured assertion exception. - [AssertionMethod] - internal static async Task WaitForAssertionAsync(this IRenderedFragmentBase renderedFragment, Action assertion, TimeSpan? timeout = null) - { - using var waiter = new WaitForAssertionHelper(renderedFragment, assertion, timeout); - - await waiter.WaitTask; - } -} diff --git a/src/bunit.core/InternalsVisibleTo.cs b/src/bunit.core/InternalsVisibleTo.cs deleted file mode 100644 index a07259efa..000000000 --- a/src/bunit.core/InternalsVisibleTo.cs +++ /dev/null @@ -1,2 +0,0 @@ -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Bunit.Core.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010001be6b1a2ca57b09b7040e2ab0993e515296ae22aef4031a4fe388a1336fe21f69c7e8610e9935de6ed18d94b5c98429f99ef62ce3d0af28a7088f856239368ea808ad4c448aa2a8075ed581f989f36ed0d0b8b1cfcaf1ff6a4506c8a99b7024b6eb56996d08e3c9c1cf5db59bff96fcc63ccad155ef7fc63aab6a69862437b6")] -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Bunit.Web.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010001be6b1a2ca57b09b7040e2ab0993e515296ae22aef4031a4fe388a1336fe21f69c7e8610e9935de6ed18d94b5c98429f99ef62ce3d0af28a7088f856239368ea808ad4c448aa2a8075ed581f989f36ed0d0b8b1cfcaf1ff6a4506c8a99b7024b6eb56996d08e3c9c1cf5db59bff96fcc63ccad155ef7fc63aab6a69862437b6")] diff --git a/src/bunit.core/bunit.core.csproj b/src/bunit.core/bunit.core.csproj deleted file mode 100644 index f50f7659f..000000000 --- a/src/bunit.core/bunit.core.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - net8.0;net9.0 - Bunit - Bunit.Core - - - - bunit.core - bUnit.core - - bUnit.core is the base library that provides support for testing Blazor components. You need to install bUnit.web as well to test web-based Blazor components. - - - - - - - - - - - - - - - - diff --git a/src/bunit.web/InternalsVisibleTo.cs b/src/bunit.web/InternalsVisibleTo.cs deleted file mode 100644 index 8761816ad..000000000 --- a/src/bunit.web/InternalsVisibleTo.cs +++ /dev/null @@ -1 +0,0 @@ -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Bunit.Web.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010001be6b1a2ca57b09b7040e2ab0993e515296ae22aef4031a4fe388a1336fe21f69c7e8610e9935de6ed18d94b5c98429f99ef62ce3d0af28a7088f856239368ea808ad4c448aa2a8075ed581f989f36ed0d0b8b1cfcaf1ff6a4506c8a99b7024b6eb56996d08e3c9c1cf5db59bff96fcc63ccad155ef7fc63aab6a69862437b6")] diff --git a/src/bunit.web/bunit.web.csproj b/src/bunit.web/bunit.web.csproj deleted file mode 100644 index 43a24a9cf..000000000 --- a/src/bunit.web/bunit.web.csproj +++ /dev/null @@ -1,58 +0,0 @@ - - - - net8.0;net9.0 - Bunit - Bunit.Web - - - - - - bunit.web - bUnit.web - - bUnit.web is the web specific parts of bUnit, that enables you to easily test and verify the output of Blazor (web) component. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/bunit.core/Asserting/ActualExpectedAssertException.cs b/src/bunit/Asserting/ActualExpectedAssertException.cs similarity index 100% rename from src/bunit.core/Asserting/ActualExpectedAssertException.cs rename to src/bunit/Asserting/ActualExpectedAssertException.cs diff --git a/src/bunit.core/Asserting/AssertionMethodAttribute.cs b/src/bunit/Asserting/AssertionMethodAttribute.cs similarity index 100% rename from src/bunit.core/Asserting/AssertionMethodAttribute.cs rename to src/bunit/Asserting/AssertionMethodAttribute.cs diff --git a/src/bunit.web/Asserting/CompareToExtensions.cs b/src/bunit/Asserting/CompareToExtensions.cs similarity index 100% rename from src/bunit.web/Asserting/CompareToExtensions.cs rename to src/bunit/Asserting/CompareToExtensions.cs diff --git a/src/bunit.web/Asserting/FocusAsyncAssertJSInteropExtensions.cs b/src/bunit/Asserting/FocusAsyncAssertJSInteropExtensions.cs similarity index 100% rename from src/bunit.web/Asserting/FocusAsyncAssertJSInteropExtensions.cs rename to src/bunit/Asserting/FocusAsyncAssertJSInteropExtensions.cs diff --git a/src/bunit.web/Asserting/FocusOnNavigateAssertJSInteropExtensions.cs b/src/bunit/Asserting/FocusOnNavigateAssertJSInteropExtensions.cs similarity index 100% rename from src/bunit.web/Asserting/FocusOnNavigateAssertJSInteropExtensions.cs rename to src/bunit/Asserting/FocusOnNavigateAssertJSInteropExtensions.cs diff --git a/src/bunit.web/Asserting/HtmlEqualException.cs b/src/bunit/Asserting/HtmlEqualException.cs similarity index 100% rename from src/bunit.web/Asserting/HtmlEqualException.cs rename to src/bunit/Asserting/HtmlEqualException.cs diff --git a/src/bunit.web/Asserting/JSInvokeCountExpectedException.cs b/src/bunit/Asserting/JSInvokeCountExpectedException.cs similarity index 100% rename from src/bunit.web/Asserting/JSInvokeCountExpectedException.cs rename to src/bunit/Asserting/JSInvokeCountExpectedException.cs diff --git a/src/bunit.web/Asserting/JSRuntimeAssertExtensions.cs b/src/bunit/Asserting/JSRuntimeAssertExtensions.cs similarity index 100% rename from src/bunit.web/Asserting/JSRuntimeAssertExtensions.cs rename to src/bunit/Asserting/JSRuntimeAssertExtensions.cs diff --git a/src/bunit.web/Asserting/MarkupMatchesAssertExtensions.cs b/src/bunit/Asserting/MarkupMatchesAssertExtensions.cs similarity index 100% rename from src/bunit.web/Asserting/MarkupMatchesAssertExtensions.cs rename to src/bunit/Asserting/MarkupMatchesAssertExtensions.cs diff --git a/src/bunit.core/ComponentFactories/ConditionalComponentFactory.cs b/src/bunit/ComponentFactories/ConditionalComponentFactory.cs similarity index 100% rename from src/bunit.core/ComponentFactories/ConditionalComponentFactory.cs rename to src/bunit/ComponentFactories/ConditionalComponentFactory.cs diff --git a/src/bunit.core/ComponentFactories/GenericComponentFactory{TComponent,TSubstituteComponent}.cs b/src/bunit/ComponentFactories/GenericComponentFactory{TComponent,TSubstituteComponent}.cs similarity index 100% rename from src/bunit.core/ComponentFactories/GenericComponentFactory{TComponent,TSubstituteComponent}.cs rename to src/bunit/ComponentFactories/GenericComponentFactory{TComponent,TSubstituteComponent}.cs diff --git a/src/bunit.core/ComponentFactories/InstanceComponentFactory{TComponent}.cs b/src/bunit/ComponentFactories/InstanceComponentFactory{TComponent}.cs similarity index 100% rename from src/bunit.core/ComponentFactories/InstanceComponentFactory{TComponent}.cs rename to src/bunit/ComponentFactories/InstanceComponentFactory{TComponent}.cs diff --git a/src/bunit.web/ComponentFactories/StubComponentFactory.cs b/src/bunit/ComponentFactories/StubComponentFactory.cs similarity index 100% rename from src/bunit.web/ComponentFactories/StubComponentFactory.cs rename to src/bunit/ComponentFactories/StubComponentFactory.cs diff --git a/src/bunit.core/ComponentFactories/TypeBasedComponentFactory{TComponent}.cs b/src/bunit/ComponentFactories/TypeBasedComponentFactory{TComponent}.cs similarity index 100% rename from src/bunit.core/ComponentFactories/TypeBasedComponentFactory{TComponent}.cs rename to src/bunit/ComponentFactories/TypeBasedComponentFactory{TComponent}.cs diff --git a/src/bunit.core/ComponentFactoryCollection.cs b/src/bunit/ComponentFactoryCollection.cs similarity index 100% rename from src/bunit.core/ComponentFactoryCollection.cs rename to src/bunit/ComponentFactoryCollection.cs diff --git a/src/bunit.core/ComponentParameter.cs b/src/bunit/ComponentParameter.cs similarity index 100% rename from src/bunit.core/ComponentParameter.cs rename to src/bunit/ComponentParameter.cs diff --git a/src/bunit.core/ComponentParameterCollection.cs b/src/bunit/ComponentParameterCollection.cs similarity index 100% rename from src/bunit.core/ComponentParameterCollection.cs rename to src/bunit/ComponentParameterCollection.cs diff --git a/src/bunit.core/ComponentParameterCollectionBuilder.cs b/src/bunit/ComponentParameterCollectionBuilder.cs similarity index 100% rename from src/bunit.core/ComponentParameterCollectionBuilder.cs rename to src/bunit/ComponentParameterCollectionBuilder.cs diff --git a/src/bunit.core/ComponentParameterFactory.cs b/src/bunit/ComponentParameterFactory.cs similarity index 100% rename from src/bunit.core/ComponentParameterFactory.cs rename to src/bunit/ComponentParameterFactory.cs diff --git a/src/bunit.web/Diffing/BlazorDiffingHelpers.cs b/src/bunit/Diffing/BlazorDiffingHelpers.cs similarity index 100% rename from src/bunit.web/Diffing/BlazorDiffingHelpers.cs rename to src/bunit/Diffing/BlazorDiffingHelpers.cs diff --git a/src/bunit.web/Diffing/DiffMarkupFormatter.cs b/src/bunit/Diffing/DiffMarkupFormatter.cs similarity index 100% rename from src/bunit.web/Diffing/DiffMarkupFormatter.cs rename to src/bunit/Diffing/DiffMarkupFormatter.cs diff --git a/src/bunit.web/Diffing/HtmlComparer.cs b/src/bunit/Diffing/HtmlComparer.cs similarity index 100% rename from src/bunit.web/Diffing/HtmlComparer.cs rename to src/bunit/Diffing/HtmlComparer.cs diff --git a/src/bunit.web/EventDispatchExtensions/ClipboardEventDispatchExtensions.cs b/src/bunit/EventDispatchExtensions/ClipboardEventDispatchExtensions.cs similarity index 100% rename from src/bunit.web/EventDispatchExtensions/ClipboardEventDispatchExtensions.cs rename to src/bunit/EventDispatchExtensions/ClipboardEventDispatchExtensions.cs diff --git a/src/bunit.web/EventDispatchExtensions/DetailsElementEventDispatchExtensions.cs b/src/bunit/EventDispatchExtensions/DetailsElementEventDispatchExtensions.cs similarity index 100% rename from src/bunit.web/EventDispatchExtensions/DetailsElementEventDispatchExtensions.cs rename to src/bunit/EventDispatchExtensions/DetailsElementEventDispatchExtensions.cs diff --git a/src/bunit.web/EventDispatchExtensions/DialogEventDispatchExtensions.cs b/src/bunit/EventDispatchExtensions/DialogEventDispatchExtensions.cs similarity index 100% rename from src/bunit.web/EventDispatchExtensions/DialogEventDispatchExtensions.cs rename to src/bunit/EventDispatchExtensions/DialogEventDispatchExtensions.cs diff --git a/src/bunit.web/EventDispatchExtensions/DragEventDispatchExtensions.cs b/src/bunit/EventDispatchExtensions/DragEventDispatchExtensions.cs similarity index 100% rename from src/bunit.web/EventDispatchExtensions/DragEventDispatchExtensions.cs rename to src/bunit/EventDispatchExtensions/DragEventDispatchExtensions.cs diff --git a/src/bunit.web/EventDispatchExtensions/FocusEventDispatchExtensions.cs b/src/bunit/EventDispatchExtensions/FocusEventDispatchExtensions.cs similarity index 100% rename from src/bunit.web/EventDispatchExtensions/FocusEventDispatchExtensions.cs rename to src/bunit/EventDispatchExtensions/FocusEventDispatchExtensions.cs diff --git a/src/bunit.web/EventDispatchExtensions/GeneralEventDispatchExtensions.cs b/src/bunit/EventDispatchExtensions/GeneralEventDispatchExtensions.cs similarity index 100% rename from src/bunit.web/EventDispatchExtensions/GeneralEventDispatchExtensions.cs rename to src/bunit/EventDispatchExtensions/GeneralEventDispatchExtensions.cs diff --git a/src/bunit.web/EventDispatchExtensions/InputEventDispatchExtensions.cs b/src/bunit/EventDispatchExtensions/InputEventDispatchExtensions.cs similarity index 100% rename from src/bunit.web/EventDispatchExtensions/InputEventDispatchExtensions.cs rename to src/bunit/EventDispatchExtensions/InputEventDispatchExtensions.cs diff --git a/src/bunit.web/EventDispatchExtensions/Key.cs b/src/bunit/EventDispatchExtensions/Key.cs similarity index 100% rename from src/bunit.web/EventDispatchExtensions/Key.cs rename to src/bunit/EventDispatchExtensions/Key.cs diff --git a/src/bunit.web/EventDispatchExtensions/KeyboardEventDispatchExtensions.cs b/src/bunit/EventDispatchExtensions/KeyboardEventDispatchExtensions.cs similarity index 100% rename from src/bunit.web/EventDispatchExtensions/KeyboardEventDispatchExtensions.cs rename to src/bunit/EventDispatchExtensions/KeyboardEventDispatchExtensions.cs diff --git a/src/bunit.web/EventDispatchExtensions/MediaEventDispatchExtensions.cs b/src/bunit/EventDispatchExtensions/MediaEventDispatchExtensions.cs similarity index 100% rename from src/bunit.web/EventDispatchExtensions/MediaEventDispatchExtensions.cs rename to src/bunit/EventDispatchExtensions/MediaEventDispatchExtensions.cs diff --git a/src/bunit.web/EventDispatchExtensions/MissingEventHandlerException.cs b/src/bunit/EventDispatchExtensions/MissingEventHandlerException.cs similarity index 100% rename from src/bunit.web/EventDispatchExtensions/MissingEventHandlerException.cs rename to src/bunit/EventDispatchExtensions/MissingEventHandlerException.cs diff --git a/src/bunit.web/EventDispatchExtensions/MouseEventDispatchExtensions.cs b/src/bunit/EventDispatchExtensions/MouseEventDispatchExtensions.cs similarity index 100% rename from src/bunit.web/EventDispatchExtensions/MouseEventDispatchExtensions.cs rename to src/bunit/EventDispatchExtensions/MouseEventDispatchExtensions.cs diff --git a/src/bunit.web/EventDispatchExtensions/PointerEventDispatchExtensions.cs b/src/bunit/EventDispatchExtensions/PointerEventDispatchExtensions.cs similarity index 100% rename from src/bunit.web/EventDispatchExtensions/PointerEventDispatchExtensions.cs rename to src/bunit/EventDispatchExtensions/PointerEventDispatchExtensions.cs diff --git a/src/bunit.web/EventDispatchExtensions/ProgressEventDispatchExtensions.cs b/src/bunit/EventDispatchExtensions/ProgressEventDispatchExtensions.cs similarity index 100% rename from src/bunit.web/EventDispatchExtensions/ProgressEventDispatchExtensions.cs rename to src/bunit/EventDispatchExtensions/ProgressEventDispatchExtensions.cs diff --git a/src/bunit.web/EventDispatchExtensions/TouchEventDispatchExtensions.cs b/src/bunit/EventDispatchExtensions/TouchEventDispatchExtensions.cs similarity index 100% rename from src/bunit.web/EventDispatchExtensions/TouchEventDispatchExtensions.cs rename to src/bunit/EventDispatchExtensions/TouchEventDispatchExtensions.cs diff --git a/src/bunit.web/EventDispatchExtensions/TriggerEventDispatchExtensions.cs b/src/bunit/EventDispatchExtensions/TriggerEventDispatchExtensions.cs similarity index 100% rename from src/bunit.web/EventDispatchExtensions/TriggerEventDispatchExtensions.cs rename to src/bunit/EventDispatchExtensions/TriggerEventDispatchExtensions.cs diff --git a/src/bunit.core/Extensions/BlazorExtensions.cs b/src/bunit/Extensions/BlazorExtensions.cs similarity index 100% rename from src/bunit.core/Extensions/BlazorExtensions.cs rename to src/bunit/Extensions/BlazorExtensions.cs diff --git a/src/bunit.core/Extensions/ComponentFactoryCollectionExtensions.cs b/src/bunit/Extensions/ComponentFactoryCollectionExtensions.cs similarity index 100% rename from src/bunit.core/Extensions/ComponentFactoryCollectionExtensions.cs rename to src/bunit/Extensions/ComponentFactoryCollectionExtensions.cs diff --git a/src/bunit.web/Extensions/ElementNotFoundException.cs b/src/bunit/Extensions/ElementNotFoundException.cs similarity index 100% rename from src/bunit.web/Extensions/ElementNotFoundException.cs rename to src/bunit/Extensions/ElementNotFoundException.cs diff --git a/src/bunit.web/Extensions/ElementRemovedFromDomException.cs b/src/bunit/Extensions/ElementRemovedFromDomException.cs similarity index 100% rename from src/bunit.web/Extensions/ElementRemovedFromDomException.cs rename to src/bunit/Extensions/ElementRemovedFromDomException.cs diff --git a/src/bunit.web/Extensions/EnumerableExtensions.cs b/src/bunit/Extensions/EnumerableExtensions.cs similarity index 100% rename from src/bunit.web/Extensions/EnumerableExtensions.cs rename to src/bunit/Extensions/EnumerableExtensions.cs diff --git a/src/bunit.web/Extensions/IRefreshableElementCollection.cs b/src/bunit/Extensions/IRefreshableElementCollection.cs similarity index 100% rename from src/bunit.web/Extensions/IRefreshableElementCollection.cs rename to src/bunit/Extensions/IRefreshableElementCollection.cs diff --git a/src/bunit.web/Extensions/InputFile/BUnitBrowserFile.cs b/src/bunit/Extensions/InputFile/BUnitBrowserFile.cs similarity index 100% rename from src/bunit.web/Extensions/InputFile/BUnitBrowserFile.cs rename to src/bunit/Extensions/InputFile/BUnitBrowserFile.cs diff --git a/src/bunit.web/Extensions/InputFile/InputFileContent.cs b/src/bunit/Extensions/InputFile/InputFileContent.cs similarity index 100% rename from src/bunit.web/Extensions/InputFile/InputFileContent.cs rename to src/bunit/Extensions/InputFile/InputFileContent.cs diff --git a/src/bunit.web/Extensions/InputFile/InputFileExtensions.cs b/src/bunit/Extensions/InputFile/InputFileExtensions.cs similarity index 100% rename from src/bunit.web/Extensions/InputFile/InputFileExtensions.cs rename to src/bunit/Extensions/InputFile/InputFileExtensions.cs diff --git a/src/bunit.web/Extensions/Internal/AngleSharpExtensions.cs b/src/bunit/Extensions/Internal/AngleSharpExtensions.cs similarity index 100% rename from src/bunit.web/Extensions/Internal/AngleSharpExtensions.cs rename to src/bunit/Extensions/Internal/AngleSharpExtensions.cs diff --git a/src/bunit.web/Extensions/Internal/AngleSharpWrapperExtensions.cs b/src/bunit/Extensions/Internal/AngleSharpWrapperExtensions.cs similarity index 100% rename from src/bunit.web/Extensions/Internal/AngleSharpWrapperExtensions.cs rename to src/bunit/Extensions/Internal/AngleSharpWrapperExtensions.cs diff --git a/src/bunit.web/Extensions/Internal/CssSelectorElementFactory.cs b/src/bunit/Extensions/Internal/CssSelectorElementFactory.cs similarity index 100% rename from src/bunit.web/Extensions/Internal/CssSelectorElementFactory.cs rename to src/bunit/Extensions/Internal/CssSelectorElementFactory.cs diff --git a/src/bunit.web/Extensions/Internal/RefreshableElementCollection.cs b/src/bunit/Extensions/Internal/RefreshableElementCollection.cs similarity index 100% rename from src/bunit.web/Extensions/Internal/RefreshableElementCollection.cs rename to src/bunit/Extensions/Internal/RefreshableElementCollection.cs diff --git a/src/bunit.core/Extensions/LoggerHelperExtensions.cs b/src/bunit/Extensions/LoggerHelperExtensions.cs similarity index 100% rename from src/bunit.core/Extensions/LoggerHelperExtensions.cs rename to src/bunit/Extensions/LoggerHelperExtensions.cs diff --git a/src/bunit.web/Extensions/NodePrintExtensions.cs b/src/bunit/Extensions/NodePrintExtensions.cs similarity index 100% rename from src/bunit.web/Extensions/NodePrintExtensions.cs rename to src/bunit/Extensions/NodePrintExtensions.cs diff --git a/src/bunit.core/Extensions/RenderedComponentRenderExtensions.cs b/src/bunit/Extensions/RenderedComponentRenderExtensions.cs similarity index 100% rename from src/bunit.core/Extensions/RenderedComponentRenderExtensions.cs rename to src/bunit/Extensions/RenderedComponentRenderExtensions.cs diff --git a/src/bunit.web/Extensions/RenderedFragmentExtensions.cs b/src/bunit/Extensions/RenderedFragmentExtensions.cs similarity index 100% rename from src/bunit.web/Extensions/RenderedFragmentExtensions.cs rename to src/bunit/Extensions/RenderedFragmentExtensions.cs diff --git a/src/bunit.core/Extensions/RenderedFragmentInvokeAsyncExtensions.cs b/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs similarity index 100% rename from src/bunit.core/Extensions/RenderedFragmentInvokeAsyncExtensions.cs rename to src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs diff --git a/src/bunit.web/Extensions/StubComponentFactoryCollectionExtensions.cs b/src/bunit/Extensions/StubComponentFactoryCollectionExtensions.cs similarity index 100% rename from src/bunit.web/Extensions/StubComponentFactoryCollectionExtensions.cs rename to src/bunit/Extensions/StubComponentFactoryCollectionExtensions.cs diff --git a/src/bunit.core/Extensions/TestContextBaseRenderExtensions.cs b/src/bunit/Extensions/TestContextBaseRenderExtensions.cs similarity index 100% rename from src/bunit.core/Extensions/TestContextBaseRenderExtensions.cs rename to src/bunit/Extensions/TestContextBaseRenderExtensions.cs diff --git a/src/bunit.web/Extensions/TestRendererExtensions.cs b/src/bunit/Extensions/TestRendererExtensions.cs similarity index 100% rename from src/bunit.web/Extensions/TestRendererExtensions.cs rename to src/bunit/Extensions/TestRendererExtensions.cs diff --git a/src/bunit.web/Extensions/TestServiceProviderExtensions.cs b/src/bunit/Extensions/TestServiceProviderExtensions.cs similarity index 100% rename from src/bunit.web/Extensions/TestServiceProviderExtensions.cs rename to src/bunit/Extensions/TestServiceProviderExtensions.cs diff --git a/src/bunit.web/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.cs b/src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForElement.cs similarity index 99% rename from src/bunit.web/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.cs rename to src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForElement.cs index e9fe9da28..f6fac5d47 100644 --- a/src/bunit.web/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.cs +++ b/src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForElement.cs @@ -7,7 +7,7 @@ namespace Bunit; /// /// Helper methods dealing with async rendering during testing. /// -public static class RenderedFragmentWaitForHelperExtensions +public static partial class RenderedFragmentWaitForHelperExtensions { /// /// Wait until an element matching the exists in the , diff --git a/src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForState.cs b/src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForState.cs new file mode 100644 index 000000000..a270ebbbf --- /dev/null +++ b/src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForState.cs @@ -0,0 +1,100 @@ +using System.Runtime.ExceptionServices; +using Bunit.Asserting; +using Bunit.Extensions.WaitForHelpers; + +namespace Bunit; + +/// +/// Helper methods dealing with async rendering during testing. +/// +public static partial class RenderedFragmentWaitForHelperExtensions +{ + /// + /// Wait until the provided action returns true, + /// or the is reached (default is one second). + /// + /// The is evaluated initially, and then each time + /// the renders. + /// + /// The render fragment or component to attempt to verify state against. + /// The predicate to invoke after each render, which must returns true when the desired state has been reached. + /// The maximum time to wait for the desired state. + /// Thrown if the throw an exception during invocation, or if the timeout has been reached. See the inner exception for details. + /// + /// If a debugger is attached the timeout is set to , giving the possibility to debug without the timeout triggering. + /// + public static void WaitForState(this IRenderedFragmentBase renderedFragment, Func statePredicate, TimeSpan? timeout = null) + { + using var waiter = new WaitForStateHelper(renderedFragment, statePredicate, timeout); + + try + { + waiter.WaitTask.GetAwaiter().GetResult(); + } + catch (AggregateException e) when (e.InnerExceptions.Count == 1) + { + ExceptionDispatchInfo.Capture(e.InnerExceptions[0]).Throw(); + } + } + + /// + /// Wait until the provided action returns true, + /// or the is reached (default is one second). + /// + /// The is evaluated initially, and then each time + /// the renders. + /// + /// The render fragment or component to attempt to verify state against. + /// The predicate to invoke after each render, which must returns true when the desired state has been reached. + /// The maximum time to wait for the desired state. + /// Thrown if the throw an exception during invocation, or if the timeout has been reached. See the inner exception for details. + internal static async Task WaitForStateAsync(this IRenderedFragmentBase renderedFragment, Func statePredicate, TimeSpan? timeout = null) + { + using var waiter = new WaitForStateHelper(renderedFragment, statePredicate, timeout); + + await waiter.WaitTask; + } + + /// + /// Wait until the provided passes (i.e. does not throw an + /// exception), or the is reached (default is one second). + /// + /// The is attempted initially, and then each time the renders. + /// + /// The rendered fragment to wait for renders from and assert against. + /// The verification or assertion to perform. + /// The maximum time to attempt the verification. + /// Thrown if the timeout has been reached. See the inner exception to see the captured assertion exception. + [AssertionMethod] + public static void WaitForAssertion(this IRenderedFragmentBase renderedFragment, Action assertion, TimeSpan? timeout = null) + { + using var waiter = new WaitForAssertionHelper(renderedFragment, assertion, timeout); + + try + { + waiter.WaitTask.GetAwaiter().GetResult(); + } + catch (AggregateException e) when (e.InnerExceptions.Count == 1) + { + ExceptionDispatchInfo.Capture(e.InnerExceptions[0]).Throw(); + } + } + + /// + /// Wait until the provided passes (i.e. does not throw an + /// exception), or the is reached (default is one second). + /// + /// The is attempted initially, and then each time the renders. + /// + /// The rendered fragment to wait for renders from and assert against. + /// The verification or assertion to perform. + /// The maximum time to attempt the verification. + /// Thrown if the timeout has been reached. See the inner exception to see the captured assertion exception. + [AssertionMethod] + internal static async Task WaitForAssertionAsync(this IRenderedFragmentBase renderedFragment, Action assertion, TimeSpan? timeout = null) + { + using var waiter = new WaitForAssertionHelper(renderedFragment, assertion, timeout); + + await waiter.WaitTask; + } +} diff --git a/src/bunit.core/Extensions/WaitForHelpers/WaitForAssertionHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForAssertionHelper.cs similarity index 100% rename from src/bunit.core/Extensions/WaitForHelpers/WaitForAssertionHelper.cs rename to src/bunit/Extensions/WaitForHelpers/WaitForAssertionHelper.cs diff --git a/src/bunit.web/Extensions/WaitForHelpers/WaitForElementHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForElementHelper.cs similarity index 100% rename from src/bunit.web/Extensions/WaitForHelpers/WaitForElementHelper.cs rename to src/bunit/Extensions/WaitForHelpers/WaitForElementHelper.cs diff --git a/src/bunit.web/Extensions/WaitForHelpers/WaitForElementsHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForElementsHelper.cs similarity index 100% rename from src/bunit.web/Extensions/WaitForHelpers/WaitForElementsHelper.cs rename to src/bunit/Extensions/WaitForHelpers/WaitForElementsHelper.cs diff --git a/src/bunit.core/Extensions/WaitForHelpers/WaitForFailedException.cs b/src/bunit/Extensions/WaitForHelpers/WaitForFailedException.cs similarity index 100% rename from src/bunit.core/Extensions/WaitForHelpers/WaitForFailedException.cs rename to src/bunit/Extensions/WaitForHelpers/WaitForFailedException.cs diff --git a/src/bunit.core/Extensions/WaitForHelpers/WaitForHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs similarity index 100% rename from src/bunit.core/Extensions/WaitForHelpers/WaitForHelper.cs rename to src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs diff --git a/src/bunit.core/Extensions/WaitForHelpers/WaitForHelperLoggerExtensions.cs b/src/bunit/Extensions/WaitForHelpers/WaitForHelperLoggerExtensions.cs similarity index 100% rename from src/bunit.core/Extensions/WaitForHelpers/WaitForHelperLoggerExtensions.cs rename to src/bunit/Extensions/WaitForHelpers/WaitForHelperLoggerExtensions.cs diff --git a/src/bunit.core/Extensions/WaitForHelpers/WaitForStateHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForStateHelper.cs similarity index 100% rename from src/bunit.core/Extensions/WaitForHelpers/WaitForStateHelper.cs rename to src/bunit/Extensions/WaitForHelpers/WaitForStateHelper.cs diff --git a/src/bunit.core/IComponentFactory.cs b/src/bunit/IComponentFactory.cs similarity index 100% rename from src/bunit.core/IComponentFactory.cs rename to src/bunit/IComponentFactory.cs diff --git a/src/bunit.web/IRenderedComponent.cs b/src/bunit/IRenderedComponent.cs similarity index 100% rename from src/bunit.web/IRenderedComponent.cs rename to src/bunit/IRenderedComponent.cs diff --git a/src/bunit.core/IRenderedComponentBase.cs b/src/bunit/IRenderedComponentBase.cs similarity index 100% rename from src/bunit.core/IRenderedComponentBase.cs rename to src/bunit/IRenderedComponentBase.cs diff --git a/src/bunit.web/IRenderedFragment.cs b/src/bunit/IRenderedFragment.cs similarity index 100% rename from src/bunit.web/IRenderedFragment.cs rename to src/bunit/IRenderedFragment.cs diff --git a/src/bunit.core/IRenderedFragmentBase.cs b/src/bunit/IRenderedFragmentBase.cs similarity index 100% rename from src/bunit.core/IRenderedFragmentBase.cs rename to src/bunit/IRenderedFragmentBase.cs diff --git a/src/bunit/InternalsVisibleTo.cs b/src/bunit/InternalsVisibleTo.cs new file mode 100644 index 000000000..a3c9cf4b0 --- /dev/null +++ b/src/bunit/InternalsVisibleTo.cs @@ -0,0 +1 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Bunit.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010001be6b1a2ca57b09b7040e2ab0993e515296ae22aef4031a4fe388a1336fe21f69c7e8610e9935de6ed18d94b5c98429f99ef62ce3d0af28a7088f856239368ea808ad4c448aa2a8075ed581f989f36ed0d0b8b1cfcaf1ff6a4506c8a99b7024b6eb56996d08e3c9c1cf5db59bff96fcc63ccad155ef7fc63aab6a69862437b6")] diff --git a/src/bunit.web/JSInterop/BunitJSInterop.cs b/src/bunit/JSInterop/BunitJSInterop.cs similarity index 100% rename from src/bunit.web/JSInterop/BunitJSInterop.cs rename to src/bunit/JSInterop/BunitJSInterop.cs diff --git a/src/bunit.web/JSInterop/BunitJSInteropSetupExtensions.cs b/src/bunit/JSInterop/BunitJSInteropSetupExtensions.cs similarity index 100% rename from src/bunit.web/JSInterop/BunitJSInteropSetupExtensions.cs rename to src/bunit/JSInterop/BunitJSInteropSetupExtensions.cs diff --git a/src/bunit.web/JSInterop/BunitJSInteropSetupExtensions.net5.cs b/src/bunit/JSInterop/BunitJSInteropSetupExtensions.net5.cs similarity index 100% rename from src/bunit.web/JSInterop/BunitJSInteropSetupExtensions.net5.cs rename to src/bunit/JSInterop/BunitJSInteropSetupExtensions.net5.cs diff --git a/src/bunit.web/JSInterop/BunitJSModuleInterop.cs b/src/bunit/JSInterop/BunitJSModuleInterop.cs similarity index 100% rename from src/bunit.web/JSInterop/BunitJSModuleInterop.cs rename to src/bunit/JSInterop/BunitJSModuleInterop.cs diff --git a/src/bunit.web/JSInterop/Implementation/BunitJSObjectReference.cs b/src/bunit/JSInterop/Implementation/BunitJSObjectReference.cs similarity index 100% rename from src/bunit.web/JSInterop/Implementation/BunitJSObjectReference.cs rename to src/bunit/JSInterop/Implementation/BunitJSObjectReference.cs diff --git a/src/bunit.web/JSInterop/Implementation/BunitJSRuntime.cs b/src/bunit/JSInterop/Implementation/BunitJSRuntime.cs similarity index 100% rename from src/bunit.web/JSInterop/Implementation/BunitJSRuntime.cs rename to src/bunit/JSInterop/Implementation/BunitJSRuntime.cs diff --git a/src/bunit.web/JSInterop/Implementation/BunitJSRuntime.net5.cs b/src/bunit/JSInterop/Implementation/BunitJSRuntime.net5.cs similarity index 100% rename from src/bunit.web/JSInterop/Implementation/BunitJSRuntime.net5.cs rename to src/bunit/JSInterop/Implementation/BunitJSRuntime.net5.cs diff --git a/src/bunit.web/JSInterop/Implementation/JSRuntimeExtensions.cs b/src/bunit/JSInterop/Implementation/JSRuntimeExtensions.cs similarity index 100% rename from src/bunit.web/JSInterop/Implementation/JSRuntimeExtensions.cs rename to src/bunit/JSInterop/Implementation/JSRuntimeExtensions.cs diff --git a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/FocusAsyncInvocationHandler.cs b/src/bunit/JSInterop/InvocationHandlers/Implementation/FocusAsyncInvocationHandler.cs similarity index 100% rename from src/bunit.web/JSInterop/InvocationHandlers/Implementation/FocusAsyncInvocationHandler.cs rename to src/bunit/JSInterop/InvocationHandlers/Implementation/FocusAsyncInvocationHandler.cs diff --git a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/FocusOnNavigateHandler.cs b/src/bunit/JSInterop/InvocationHandlers/Implementation/FocusOnNavigateHandler.cs similarity index 100% rename from src/bunit.web/JSInterop/InvocationHandlers/Implementation/FocusOnNavigateHandler.cs rename to src/bunit/JSInterop/InvocationHandlers/Implementation/FocusOnNavigateHandler.cs diff --git a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/InputFileInvocationHandler.cs b/src/bunit/JSInterop/InvocationHandlers/Implementation/InputFileInvocationHandler.cs similarity index 100% rename from src/bunit.web/JSInterop/InvocationHandlers/Implementation/InputFileInvocationHandler.cs rename to src/bunit/JSInterop/InvocationHandlers/Implementation/InputFileInvocationHandler.cs diff --git a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/JSObjectReferenceInvocationHandler.cs b/src/bunit/JSInterop/InvocationHandlers/Implementation/JSObjectReferenceInvocationHandler.cs similarity index 100% rename from src/bunit.web/JSInterop/InvocationHandlers/Implementation/JSObjectReferenceInvocationHandler.cs rename to src/bunit/JSInterop/InvocationHandlers/Implementation/JSObjectReferenceInvocationHandler.cs diff --git a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/LooseModeJSObjectReferenceInvocationHandler.cs b/src/bunit/JSInterop/InvocationHandlers/Implementation/LooseModeJSObjectReferenceInvocationHandler.cs similarity index 100% rename from src/bunit.web/JSInterop/InvocationHandlers/Implementation/LooseModeJSObjectReferenceInvocationHandler.cs rename to src/bunit/JSInterop/InvocationHandlers/Implementation/LooseModeJSObjectReferenceInvocationHandler.cs diff --git a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/NavigationLockDisableNavigationPromptInvocationHandler.cs b/src/bunit/JSInterop/InvocationHandlers/Implementation/NavigationLockDisableNavigationPromptInvocationHandler.cs similarity index 100% rename from src/bunit.web/JSInterop/InvocationHandlers/Implementation/NavigationLockDisableNavigationPromptInvocationHandler.cs rename to src/bunit/JSInterop/InvocationHandlers/Implementation/NavigationLockDisableNavigationPromptInvocationHandler.cs diff --git a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/NavigationLockEnableNavigationPromptInvocationHandler.cs b/src/bunit/JSInterop/InvocationHandlers/Implementation/NavigationLockEnableNavigationPromptInvocationHandler.cs similarity index 100% rename from src/bunit.web/JSInterop/InvocationHandlers/Implementation/NavigationLockEnableNavigationPromptInvocationHandler.cs rename to src/bunit/JSInterop/InvocationHandlers/Implementation/NavigationLockEnableNavigationPromptInvocationHandler.cs diff --git a/src/bunit.web/JSInterop/InvocationHandlers/Implementation/VirtualizeJSRuntimeInvocationHandler.cs b/src/bunit/JSInterop/InvocationHandlers/Implementation/VirtualizeJSRuntimeInvocationHandler.cs similarity index 100% rename from src/bunit.web/JSInterop/InvocationHandlers/Implementation/VirtualizeJSRuntimeInvocationHandler.cs rename to src/bunit/JSInterop/InvocationHandlers/Implementation/VirtualizeJSRuntimeInvocationHandler.cs diff --git a/src/bunit.web/JSInterop/InvocationHandlers/JSRuntimeInvocationHandler.cs b/src/bunit/JSInterop/InvocationHandlers/JSRuntimeInvocationHandler.cs similarity index 100% rename from src/bunit.web/JSInterop/InvocationHandlers/JSRuntimeInvocationHandler.cs rename to src/bunit/JSInterop/InvocationHandlers/JSRuntimeInvocationHandler.cs diff --git a/src/bunit.web/JSInterop/InvocationHandlers/JSRuntimeInvocationHandlerBase{TResult}.cs b/src/bunit/JSInterop/InvocationHandlers/JSRuntimeInvocationHandlerBase{TResult}.cs similarity index 100% rename from src/bunit.web/JSInterop/InvocationHandlers/JSRuntimeInvocationHandlerBase{TResult}.cs rename to src/bunit/JSInterop/InvocationHandlers/JSRuntimeInvocationHandlerBase{TResult}.cs diff --git a/src/bunit.web/JSInterop/InvocationHandlers/JSRuntimeInvocationHandler{TResult}.cs b/src/bunit/JSInterop/InvocationHandlers/JSRuntimeInvocationHandler{TResult}.cs similarity index 100% rename from src/bunit.web/JSInterop/InvocationHandlers/JSRuntimeInvocationHandler{TResult}.cs rename to src/bunit/JSInterop/InvocationHandlers/JSRuntimeInvocationHandler{TResult}.cs diff --git a/src/bunit.web/JSInterop/InvocationMatcher.cs b/src/bunit/JSInterop/InvocationMatcher.cs similarity index 100% rename from src/bunit.web/JSInterop/InvocationMatcher.cs rename to src/bunit/JSInterop/InvocationMatcher.cs diff --git a/src/bunit.web/JSInterop/JSRuntimeInvocation.cs b/src/bunit/JSInterop/JSRuntimeInvocation.cs similarity index 100% rename from src/bunit.web/JSInterop/JSRuntimeInvocation.cs rename to src/bunit/JSInterop/JSRuntimeInvocation.cs diff --git a/src/bunit.web/JSInterop/JSRuntimeInvocationDictionary.cs b/src/bunit/JSInterop/JSRuntimeInvocationDictionary.cs similarity index 100% rename from src/bunit.web/JSInterop/JSRuntimeInvocationDictionary.cs rename to src/bunit/JSInterop/JSRuntimeInvocationDictionary.cs diff --git a/src/bunit.web/JSInterop/JSRuntimeMode.cs b/src/bunit/JSInterop/JSRuntimeMode.cs similarity index 100% rename from src/bunit.web/JSInterop/JSRuntimeMode.cs rename to src/bunit/JSInterop/JSRuntimeMode.cs diff --git a/src/bunit.web/JSInterop/JSRuntimeUnhandledInvocationException.cs b/src/bunit/JSInterop/JSRuntimeUnhandledInvocationException.cs similarity index 100% rename from src/bunit.web/JSInterop/JSRuntimeUnhandledInvocationException.cs rename to src/bunit/JSInterop/JSRuntimeUnhandledInvocationException.cs diff --git a/src/bunit.core/ParameterException.cs b/src/bunit/ParameterException.cs similarity index 100% rename from src/bunit.core/ParameterException.cs rename to src/bunit/ParameterException.cs diff --git a/src/bunit.core/Rendering/BunitComponentActivator.cs b/src/bunit/Rendering/BunitComponentActivator.cs similarity index 100% rename from src/bunit.core/Rendering/BunitComponentActivator.cs rename to src/bunit/Rendering/BunitComponentActivator.cs diff --git a/src/bunit.web/Rendering/BunitHtmlParser.cs b/src/bunit/Rendering/BunitHtmlParser.cs similarity index 100% rename from src/bunit.web/Rendering/BunitHtmlParser.cs rename to src/bunit/Rendering/BunitHtmlParser.cs diff --git a/src/bunit.core/Rendering/ComponentDisposedException.cs b/src/bunit/Rendering/ComponentDisposedException.cs similarity index 100% rename from src/bunit.core/Rendering/ComponentDisposedException.cs rename to src/bunit/Rendering/ComponentDisposedException.cs diff --git a/src/bunit.core/Rendering/ComponentNotFoundException.cs b/src/bunit/Rendering/ComponentNotFoundException.cs similarity index 100% rename from src/bunit.core/Rendering/ComponentNotFoundException.cs rename to src/bunit/Rendering/ComponentNotFoundException.cs diff --git a/src/bunit.core/Rendering/FragmentContainer.cs b/src/bunit/Rendering/FragmentContainer.cs similarity index 100% rename from src/bunit.core/Rendering/FragmentContainer.cs rename to src/bunit/Rendering/FragmentContainer.cs diff --git a/src/bunit.core/Rendering/IRenderedComponentActivator.cs b/src/bunit/Rendering/IRenderedComponentActivator.cs similarity index 100% rename from src/bunit.core/Rendering/IRenderedComponentActivator.cs rename to src/bunit/Rendering/IRenderedComponentActivator.cs diff --git a/src/bunit.core/Rendering/ITestRenderer.cs b/src/bunit/Rendering/ITestRenderer.cs similarity index 100% rename from src/bunit.core/Rendering/ITestRenderer.cs rename to src/bunit/Rendering/ITestRenderer.cs diff --git a/src/bunit.web/Rendering/Internal/BunitHtmlParserHelpers.cs b/src/bunit/Rendering/Internal/BunitHtmlParserHelpers.cs similarity index 100% rename from src/bunit.web/Rendering/Internal/BunitHtmlParserHelpers.cs rename to src/bunit/Rendering/Internal/BunitHtmlParserHelpers.cs diff --git a/src/bunit.web/Rendering/Internal/Htmlizer.cs b/src/bunit/Rendering/Internal/Htmlizer.cs similarity index 100% rename from src/bunit.web/Rendering/Internal/Htmlizer.cs rename to src/bunit/Rendering/Internal/Htmlizer.cs diff --git a/src/bunit.core/Rendering/RenderEvent.cs b/src/bunit/Rendering/RenderEvent.cs similarity index 100% rename from src/bunit.core/Rendering/RenderEvent.cs rename to src/bunit/Rendering/RenderEvent.cs diff --git a/src/bunit.core/Rendering/RenderTreeFrameDictionary.cs b/src/bunit/Rendering/RenderTreeFrameDictionary.cs similarity index 100% rename from src/bunit.core/Rendering/RenderTreeFrameDictionary.cs rename to src/bunit/Rendering/RenderTreeFrameDictionary.cs diff --git a/src/bunit.web/Rendering/RenderedComponent.cs b/src/bunit/Rendering/RenderedComponent.cs similarity index 100% rename from src/bunit.web/Rendering/RenderedComponent.cs rename to src/bunit/Rendering/RenderedComponent.cs diff --git a/src/bunit.web/Rendering/RenderedComponentActivator.cs b/src/bunit/Rendering/RenderedComponentActivator.cs similarity index 100% rename from src/bunit.web/Rendering/RenderedComponentActivator.cs rename to src/bunit/Rendering/RenderedComponentActivator.cs diff --git a/src/bunit.web/Rendering/RenderedFragment.cs b/src/bunit/Rendering/RenderedFragment.cs similarity index 100% rename from src/bunit.web/Rendering/RenderedFragment.cs rename to src/bunit/Rendering/RenderedFragment.cs diff --git a/src/bunit.core/Rendering/RootComponent.cs b/src/bunit/Rendering/RootComponent.cs similarity index 100% rename from src/bunit.core/Rendering/RootComponent.cs rename to src/bunit/Rendering/RootComponent.cs diff --git a/src/bunit.core/Rendering/RootRenderTree.cs b/src/bunit/Rendering/RootRenderTree.cs similarity index 100% rename from src/bunit.core/Rendering/RootRenderTree.cs rename to src/bunit/Rendering/RootRenderTree.cs diff --git a/src/bunit.core/Rendering/RootRenderTreeRegistration.cs b/src/bunit/Rendering/RootRenderTreeRegistration.cs similarity index 100% rename from src/bunit.core/Rendering/RootRenderTreeRegistration.cs rename to src/bunit/Rendering/RootRenderTreeRegistration.cs diff --git a/src/bunit.core/Rendering/TestRenderer.cs b/src/bunit/Rendering/TestRenderer.cs similarity index 100% rename from src/bunit.core/Rendering/TestRenderer.cs rename to src/bunit/Rendering/TestRenderer.cs diff --git a/src/bunit.core/Rendering/TestRendererLoggerExtensions.cs b/src/bunit/Rendering/TestRendererLoggerExtensions.cs similarity index 100% rename from src/bunit.core/Rendering/TestRendererLoggerExtensions.cs rename to src/bunit/Rendering/TestRendererLoggerExtensions.cs diff --git a/src/bunit.core/Rendering/UnknownEventHandlerIdException.cs b/src/bunit/Rendering/UnknownEventHandlerIdException.cs similarity index 100% rename from src/bunit.core/Rendering/UnknownEventHandlerIdException.cs rename to src/bunit/Rendering/UnknownEventHandlerIdException.cs diff --git a/src/bunit.web/Rendering/WebTestRenderer.cs b/src/bunit/Rendering/WebTestRenderer.cs similarity index 100% rename from src/bunit.web/Rendering/WebTestRenderer.cs rename to src/bunit/Rendering/WebTestRenderer.cs diff --git a/src/bunit.web/TestContext.cs b/src/bunit/TestContext.cs similarity index 100% rename from src/bunit.web/TestContext.cs rename to src/bunit/TestContext.cs diff --git a/src/bunit.core/TestContextBase.cs b/src/bunit/TestContextBase.cs similarity index 100% rename from src/bunit.core/TestContextBase.cs rename to src/bunit/TestContextBase.cs diff --git a/src/bunit.web/TestContextWrapper.cs b/src/bunit/TestContextWrapper.cs similarity index 100% rename from src/bunit.web/TestContextWrapper.cs rename to src/bunit/TestContextWrapper.cs diff --git a/src/bunit.web/TestDoubles/Authorization/AuthorizationState.cs b/src/bunit/TestDoubles/Authorization/AuthorizationState.cs similarity index 100% rename from src/bunit.web/TestDoubles/Authorization/AuthorizationState.cs rename to src/bunit/TestDoubles/Authorization/AuthorizationState.cs diff --git a/src/bunit.web/TestDoubles/Authorization/FakeAuthenticationStateProvider.cs b/src/bunit/TestDoubles/Authorization/FakeAuthenticationStateProvider.cs similarity index 100% rename from src/bunit.web/TestDoubles/Authorization/FakeAuthenticationStateProvider.cs rename to src/bunit/TestDoubles/Authorization/FakeAuthenticationStateProvider.cs diff --git a/src/bunit.web/TestDoubles/Authorization/FakeAuthorizationExtensions.cs b/src/bunit/TestDoubles/Authorization/FakeAuthorizationExtensions.cs similarity index 100% rename from src/bunit.web/TestDoubles/Authorization/FakeAuthorizationExtensions.cs rename to src/bunit/TestDoubles/Authorization/FakeAuthorizationExtensions.cs diff --git a/src/bunit.web/TestDoubles/Authorization/FakeAuthorizationPolicyProvider.cs b/src/bunit/TestDoubles/Authorization/FakeAuthorizationPolicyProvider.cs similarity index 100% rename from src/bunit.web/TestDoubles/Authorization/FakeAuthorizationPolicyProvider.cs rename to src/bunit/TestDoubles/Authorization/FakeAuthorizationPolicyProvider.cs diff --git a/src/bunit.web/TestDoubles/Authorization/FakeAuthorizationService.cs b/src/bunit/TestDoubles/Authorization/FakeAuthorizationService.cs similarity index 100% rename from src/bunit.web/TestDoubles/Authorization/FakeAuthorizationService.cs rename to src/bunit/TestDoubles/Authorization/FakeAuthorizationService.cs diff --git a/src/bunit.web/TestDoubles/Authorization/MissingFakeAuthorizationException.cs b/src/bunit/TestDoubles/Authorization/MissingFakeAuthorizationException.cs similarity index 100% rename from src/bunit.web/TestDoubles/Authorization/MissingFakeAuthorizationException.cs rename to src/bunit/TestDoubles/Authorization/MissingFakeAuthorizationException.cs diff --git a/src/bunit.web/TestDoubles/Authorization/PlaceholderAuthenticationStateProvider.cs b/src/bunit/TestDoubles/Authorization/PlaceholderAuthenticationStateProvider.cs similarity index 100% rename from src/bunit.web/TestDoubles/Authorization/PlaceholderAuthenticationStateProvider.cs rename to src/bunit/TestDoubles/Authorization/PlaceholderAuthenticationStateProvider.cs diff --git a/src/bunit.web/TestDoubles/Authorization/PlaceholderAuthorizationService.cs b/src/bunit/TestDoubles/Authorization/PlaceholderAuthorizationService.cs similarity index 100% rename from src/bunit.web/TestDoubles/Authorization/PlaceholderAuthorizationService.cs rename to src/bunit/TestDoubles/Authorization/PlaceholderAuthorizationService.cs diff --git a/src/bunit.web/TestDoubles/Authorization/TestAuthorizationContext.cs b/src/bunit/TestDoubles/Authorization/TestAuthorizationContext.cs similarity index 100% rename from src/bunit.web/TestDoubles/Authorization/TestAuthorizationContext.cs rename to src/bunit/TestDoubles/Authorization/TestAuthorizationContext.cs diff --git a/src/bunit.web/TestDoubles/Authorization/TestPolicyRequirement.cs b/src/bunit/TestDoubles/Authorization/TestPolicyRequirement.cs similarity index 100% rename from src/bunit.web/TestDoubles/Authorization/TestPolicyRequirement.cs rename to src/bunit/TestDoubles/Authorization/TestPolicyRequirement.cs diff --git a/src/bunit.web/TestDoubles/Components/CapturedParameterView{TComponent}.cs b/src/bunit/TestDoubles/Components/CapturedParameterView{TComponent}.cs similarity index 100% rename from src/bunit.web/TestDoubles/Components/CapturedParameterView{TComponent}.cs rename to src/bunit/TestDoubles/Components/CapturedParameterView{TComponent}.cs diff --git a/src/bunit.web/TestDoubles/Components/ComponentDoubleBase{TComponent}.cs b/src/bunit/TestDoubles/Components/ComponentDoubleBase{TComponent}.cs similarity index 100% rename from src/bunit.web/TestDoubles/Components/ComponentDoubleBase{TComponent}.cs rename to src/bunit/TestDoubles/Components/ComponentDoubleBase{TComponent}.cs diff --git a/src/bunit.web/TestDoubles/Components/ParameterNotFoundException.cs b/src/bunit/TestDoubles/Components/ParameterNotFoundException.cs similarity index 100% rename from src/bunit.web/TestDoubles/Components/ParameterNotFoundException.cs rename to src/bunit/TestDoubles/Components/ParameterNotFoundException.cs diff --git a/src/bunit.web/TestDoubles/Components/Stub{TComponent}.cs b/src/bunit/TestDoubles/Components/Stub{TComponent}.cs similarity index 100% rename from src/bunit.web/TestDoubles/Components/Stub{TComponent}.cs rename to src/bunit/TestDoubles/Components/Stub{TComponent}.cs diff --git a/src/bunit.web/TestDoubles/ErrorBoundary/BunitErrorBoundaryLogger.cs b/src/bunit/TestDoubles/ErrorBoundary/BunitErrorBoundaryLogger.cs similarity index 100% rename from src/bunit.web/TestDoubles/ErrorBoundary/BunitErrorBoundaryLogger.cs rename to src/bunit/TestDoubles/ErrorBoundary/BunitErrorBoundaryLogger.cs diff --git a/src/bunit.web/TestDoubles/HttpClient/MissingMockHttpClientException.cs b/src/bunit/TestDoubles/HttpClient/MissingMockHttpClientException.cs similarity index 100% rename from src/bunit.web/TestDoubles/HttpClient/MissingMockHttpClientException.cs rename to src/bunit/TestDoubles/HttpClient/MissingMockHttpClientException.cs diff --git a/src/bunit.web/TestDoubles/HttpClient/PlaceholderHttpClient.cs b/src/bunit/TestDoubles/HttpClient/PlaceholderHttpClient.cs similarity index 100% rename from src/bunit.web/TestDoubles/HttpClient/PlaceholderHttpClient.cs rename to src/bunit/TestDoubles/HttpClient/PlaceholderHttpClient.cs diff --git a/src/bunit.web/TestDoubles/Localization/MissingMockStringLocalizationException.cs b/src/bunit/TestDoubles/Localization/MissingMockStringLocalizationException.cs similarity index 100% rename from src/bunit.web/TestDoubles/Localization/MissingMockStringLocalizationException.cs rename to src/bunit/TestDoubles/Localization/MissingMockStringLocalizationException.cs diff --git a/src/bunit.web/TestDoubles/Localization/PlaceholderStringLocalization.cs b/src/bunit/TestDoubles/Localization/PlaceholderStringLocalization.cs similarity index 100% rename from src/bunit.web/TestDoubles/Localization/PlaceholderStringLocalization.cs rename to src/bunit/TestDoubles/Localization/PlaceholderStringLocalization.cs diff --git a/src/bunit.web/TestDoubles/NavigationInterception/FakeNavigationInterception.cs b/src/bunit/TestDoubles/NavigationInterception/FakeNavigationInterception.cs similarity index 100% rename from src/bunit.web/TestDoubles/NavigationInterception/FakeNavigationInterception.cs rename to src/bunit/TestDoubles/NavigationInterception/FakeNavigationInterception.cs diff --git a/src/bunit.web/TestDoubles/NavigationManager/FakeNavigationManager.cs b/src/bunit/TestDoubles/NavigationManager/FakeNavigationManager.cs similarity index 100% rename from src/bunit.web/TestDoubles/NavigationManager/FakeNavigationManager.cs rename to src/bunit/TestDoubles/NavigationManager/FakeNavigationManager.cs diff --git a/src/bunit.web/TestDoubles/NavigationManager/FakeSignOutSessionStateManager.cs b/src/bunit/TestDoubles/NavigationManager/FakeSignOutSessionStateManager.cs similarity index 100% rename from src/bunit.web/TestDoubles/NavigationManager/FakeSignOutSessionStateManager.cs rename to src/bunit/TestDoubles/NavigationManager/FakeSignOutSessionStateManager.cs diff --git a/src/bunit.web/TestDoubles/NavigationManager/NavigationHistory.cs b/src/bunit/TestDoubles/NavigationManager/NavigationHistory.cs similarity index 100% rename from src/bunit.web/TestDoubles/NavigationManager/NavigationHistory.cs rename to src/bunit/TestDoubles/NavigationManager/NavigationHistory.cs diff --git a/src/bunit.web/TestDoubles/NavigationManager/NavigationState.cs b/src/bunit/TestDoubles/NavigationManager/NavigationState.cs similarity index 100% rename from src/bunit.web/TestDoubles/NavigationManager/NavigationState.cs rename to src/bunit/TestDoubles/NavigationManager/NavigationState.cs diff --git a/src/bunit.core/TestDoubles/PersistentComponentState/FakePersistentComponentState.cs b/src/bunit/TestDoubles/PersistentComponentState/FakePersistentComponentState.cs similarity index 100% rename from src/bunit.core/TestDoubles/PersistentComponentState/FakePersistentComponentState.cs rename to src/bunit/TestDoubles/PersistentComponentState/FakePersistentComponentState.cs diff --git a/src/bunit.core/TestDoubles/PersistentComponentState/FakePersistentComponentStateStore.cs b/src/bunit/TestDoubles/PersistentComponentState/FakePersistentComponentStateStore.cs similarity index 100% rename from src/bunit.core/TestDoubles/PersistentComponentState/FakePersistentComponentStateStore.cs rename to src/bunit/TestDoubles/PersistentComponentState/FakePersistentComponentStateStore.cs diff --git a/src/bunit.core/TestDoubles/PersistentComponentState/TestContextBaseExtensions.cs b/src/bunit/TestDoubles/PersistentComponentState/TestContextBaseExtensions.cs similarity index 100% rename from src/bunit.core/TestDoubles/PersistentComponentState/TestContextBaseExtensions.cs rename to src/bunit/TestDoubles/PersistentComponentState/TestContextBaseExtensions.cs diff --git a/src/bunit.web/TestDoubles/ScrollToLocationHash/BunitScrollToLocationHash.cs b/src/bunit/TestDoubles/ScrollToLocationHash/BunitScrollToLocationHash.cs similarity index 100% rename from src/bunit.web/TestDoubles/ScrollToLocationHash/BunitScrollToLocationHash.cs rename to src/bunit/TestDoubles/ScrollToLocationHash/BunitScrollToLocationHash.cs diff --git a/src/bunit.web/TestDoubles/WebAssemblyHostEnvironment/FakeWebAssemblyHostEnvironment.cs b/src/bunit/TestDoubles/WebAssemblyHostEnvironment/FakeWebAssemblyHostEnvironment.cs similarity index 100% rename from src/bunit.web/TestDoubles/WebAssemblyHostEnvironment/FakeWebAssemblyHostEnvironment.cs rename to src/bunit/TestDoubles/WebAssemblyHostEnvironment/FakeWebAssemblyHostEnvironment.cs diff --git a/src/bunit.core/TestServiceProvider.cs b/src/bunit/TestServiceProvider.cs similarity index 100% rename from src/bunit.core/TestServiceProvider.cs rename to src/bunit/TestServiceProvider.cs diff --git a/src/bunit/bunit.csproj b/src/bunit/bunit.csproj index 991e3c475..6178b2968 100644 --- a/src/bunit/bunit.csproj +++ b/src/bunit/bunit.csproj @@ -1,9 +1,6 @@ net8.0;net9.0 - true - false - false @@ -21,8 +18,30 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/src.sln b/src/src.sln deleted file mode 100644 index 47e5b30dc..000000000 --- a/src/src.sln +++ /dev/null @@ -1,60 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.5.002.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit", "bunit\bunit.csproj", "{91DF582A-7C2B-4437-AB28-EE9FBED907A0}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit.core", "bunit.core\bunit.core.csproj", "{EC350F53-49A3-498A-B349-59BC6C0EB236}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit.template", "bunit.template\bunit.template.csproj", "{1E035DBC-EFCF-4A4B-86A3-A4AA0E3A1EEE}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit.web", "bunit.web\bunit.web.csproj", "{73994570-A89F-4726-8A6F-DFA53947DD29}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bunit.web.query", "bunit.web.query\bunit.web.query.csproj", "{F3C4F8A2-1B48-4E70-B66B-E14E97C38927}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "bunit.template (1)", "bunit.template (1)", "{C7995CF2-FFAB-4409-8AFB-74698442B784}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Company.BlazorTests1", "bunit.template\template\Company.BlazorTests1.csproj", "{537418EE-DC2C-4611-B16A-B986D41740EE}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {91DF582A-7C2B-4437-AB28-EE9FBED907A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {91DF582A-7C2B-4437-AB28-EE9FBED907A0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {91DF582A-7C2B-4437-AB28-EE9FBED907A0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {91DF582A-7C2B-4437-AB28-EE9FBED907A0}.Release|Any CPU.Build.0 = Release|Any CPU - {EC350F53-49A3-498A-B349-59BC6C0EB236}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EC350F53-49A3-498A-B349-59BC6C0EB236}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EC350F53-49A3-498A-B349-59BC6C0EB236}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EC350F53-49A3-498A-B349-59BC6C0EB236}.Release|Any CPU.Build.0 = Release|Any CPU - {1E035DBC-EFCF-4A4B-86A3-A4AA0E3A1EEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1E035DBC-EFCF-4A4B-86A3-A4AA0E3A1EEE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1E035DBC-EFCF-4A4B-86A3-A4AA0E3A1EEE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1E035DBC-EFCF-4A4B-86A3-A4AA0E3A1EEE}.Release|Any CPU.Build.0 = Release|Any CPU - {73994570-A89F-4726-8A6F-DFA53947DD29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {73994570-A89F-4726-8A6F-DFA53947DD29}.Debug|Any CPU.Build.0 = Debug|Any CPU - {73994570-A89F-4726-8A6F-DFA53947DD29}.Release|Any CPU.ActiveCfg = Release|Any CPU - {73994570-A89F-4726-8A6F-DFA53947DD29}.Release|Any CPU.Build.0 = Release|Any CPU - {F3C4F8A2-1B48-4E70-B66B-E14E97C38927}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F3C4F8A2-1B48-4E70-B66B-E14E97C38927}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F3C4F8A2-1B48-4E70-B66B-E14E97C38927}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F3C4F8A2-1B48-4E70-B66B-E14E97C38927}.Release|Any CPU.Build.0 = Release|Any CPU - {537418EE-DC2C-4611-B16A-B986D41740EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {537418EE-DC2C-4611-B16A-B986D41740EE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {537418EE-DC2C-4611-B16A-B986D41740EE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {537418EE-DC2C-4611-B16A-B986D41740EE}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {537418EE-DC2C-4611-B16A-B986D41740EE} = {C7995CF2-FFAB-4409-8AFB-74698442B784} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {28522EFE-F7F9-42C1-9A91-EC9D8EC08CDB} - EndGlobalSection -EndGlobal diff --git a/tests/bunit.generators.tests/bunit.generators.tests.csproj b/tests/bunit.generators.tests/bunit.generators.tests.csproj index e0cdb9754..9c4e1408f 100644 --- a/tests/bunit.generators.tests/bunit.generators.tests.csproj +++ b/tests/bunit.generators.tests/bunit.generators.tests.csproj @@ -35,7 +35,7 @@ - + diff --git a/tests/bunit.web.tests/Assembly.cs b/tests/bunit.tests/Assembly.cs similarity index 100% rename from tests/bunit.web.tests/Assembly.cs rename to tests/bunit.tests/Assembly.cs diff --git a/tests/bunit.web.tests/Asserting/CompareToDiffingExtensionsTest.cs b/tests/bunit.tests/Asserting/CompareToDiffingExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/Asserting/CompareToDiffingExtensionsTest.cs rename to tests/bunit.tests/Asserting/CompareToDiffingExtensionsTest.cs diff --git a/tests/bunit.web.tests/Asserting/JSRuntimeAssertExtensionsTest.cs b/tests/bunit.tests/Asserting/JSRuntimeAssertExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/Asserting/JSRuntimeAssertExtensionsTest.cs rename to tests/bunit.tests/Asserting/JSRuntimeAssertExtensionsTest.cs diff --git a/tests/bunit.web.tests/Asserting/MarkupMatchesAssertExtensionsTest.cs b/tests/bunit.tests/Asserting/MarkupMatchesAssertExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/Asserting/MarkupMatchesAssertExtensionsTest.cs rename to tests/bunit.tests/Asserting/MarkupMatchesAssertExtensionsTest.cs diff --git a/tests/bunit.web.tests/Asserting/MarkupMatchesAssertExtensionsTest.net5.cs b/tests/bunit.tests/Asserting/MarkupMatchesAssertExtensionsTest.net5.cs similarity index 100% rename from tests/bunit.web.tests/Asserting/MarkupMatchesAssertExtensionsTest.net5.cs rename to tests/bunit.tests/Asserting/MarkupMatchesAssertExtensionsTest.net5.cs diff --git a/tests/bunit.web.tests/Asserting/MarkupMatchesTests.razor b/tests/bunit.tests/Asserting/MarkupMatchesTests.razor similarity index 100% rename from tests/bunit.web.tests/Asserting/MarkupMatchesTests.razor rename to tests/bunit.tests/Asserting/MarkupMatchesTests.razor diff --git a/tests/bunit.web.tests/BlazorE2E/ComponentRenderingTest.cs b/tests/bunit.tests/BlazorE2E/ComponentRenderingTest.cs similarity index 100% rename from tests/bunit.web.tests/BlazorE2E/ComponentRenderingTest.cs rename to tests/bunit.tests/BlazorE2E/ComponentRenderingTest.cs diff --git a/tests/bunit.core.tests/ComponentFactories/ConditionalComponentFactoryTest.cs b/tests/bunit.tests/ComponentFactories/ConditionalComponentFactoryTest.cs similarity index 100% rename from tests/bunit.core.tests/ComponentFactories/ConditionalComponentFactoryTest.cs rename to tests/bunit.tests/ComponentFactories/ConditionalComponentFactoryTest.cs diff --git a/tests/bunit.core.tests/ComponentFactories/GenericComponentFactoryTest.cs b/tests/bunit.tests/ComponentFactories/GenericComponentFactoryTest.cs similarity index 100% rename from tests/bunit.core.tests/ComponentFactories/GenericComponentFactoryTest.cs rename to tests/bunit.tests/ComponentFactories/GenericComponentFactoryTest.cs diff --git a/tests/bunit.core.tests/ComponentFactories/InstanceComponentFactoryTest.cs b/tests/bunit.tests/ComponentFactories/InstanceComponentFactoryTest.cs similarity index 100% rename from tests/bunit.core.tests/ComponentFactories/InstanceComponentFactoryTest.cs rename to tests/bunit.tests/ComponentFactories/InstanceComponentFactoryTest.cs diff --git a/tests/bunit.web.tests/ComponentFactories/StubComponentFactoryTest.cs b/tests/bunit.tests/ComponentFactories/StubComponentFactoryTest.cs similarity index 100% rename from tests/bunit.web.tests/ComponentFactories/StubComponentFactoryTest.cs rename to tests/bunit.tests/ComponentFactories/StubComponentFactoryTest.cs diff --git a/tests/bunit.core.tests/ComponentFactories/TypeBasedComponentFactoryTest.cs b/tests/bunit.tests/ComponentFactories/TypeBasedComponentFactoryTest.cs similarity index 100% rename from tests/bunit.core.tests/ComponentFactories/TypeBasedComponentFactoryTest.cs rename to tests/bunit.tests/ComponentFactories/TypeBasedComponentFactoryTest.cs diff --git a/tests/bunit.core.tests/ComponentParameterCollectionBuilderTests.cs b/tests/bunit.tests/ComponentParameterCollectionBuilderTests.cs similarity index 100% rename from tests/bunit.core.tests/ComponentParameterCollectionBuilderTests.cs rename to tests/bunit.tests/ComponentParameterCollectionBuilderTests.cs diff --git a/tests/bunit.core.tests/ComponentParameterCollectionBuilderTests.razor b/tests/bunit.tests/ComponentParameterCollectionBuilderTests.razor similarity index 100% rename from tests/bunit.core.tests/ComponentParameterCollectionBuilderTests.razor rename to tests/bunit.tests/ComponentParameterCollectionBuilderTests.razor diff --git a/tests/bunit.core.tests/ComponentParameterCollectionTest.cs b/tests/bunit.tests/ComponentParameterCollectionTest.cs similarity index 100% rename from tests/bunit.core.tests/ComponentParameterCollectionTest.cs rename to tests/bunit.tests/ComponentParameterCollectionTest.cs diff --git a/tests/bunit.core.tests/ComponentParameterFactoryTest.cs b/tests/bunit.tests/ComponentParameterFactoryTest.cs similarity index 100% rename from tests/bunit.core.tests/ComponentParameterFactoryTest.cs rename to tests/bunit.tests/ComponentParameterFactoryTest.cs diff --git a/tests/bunit.web.tests/EventDispatchExtensions/ClipboardEventDispatchExtensionsTest.cs b/tests/bunit.tests/EventDispatchExtensions/ClipboardEventDispatchExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/EventDispatchExtensions/ClipboardEventDispatchExtensionsTest.cs rename to tests/bunit.tests/EventDispatchExtensions/ClipboardEventDispatchExtensionsTest.cs diff --git a/tests/bunit.web.tests/EventDispatchExtensions/DetailsElementEventDispatcherExtensionsTest.cs b/tests/bunit.tests/EventDispatchExtensions/DetailsElementEventDispatcherExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/EventDispatchExtensions/DetailsElementEventDispatcherExtensionsTest.cs rename to tests/bunit.tests/EventDispatchExtensions/DetailsElementEventDispatcherExtensionsTest.cs diff --git a/tests/bunit.web.tests/EventDispatchExtensions/DragEventDispatchExtensionsTest.cs b/tests/bunit.tests/EventDispatchExtensions/DragEventDispatchExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/EventDispatchExtensions/DragEventDispatchExtensionsTest.cs rename to tests/bunit.tests/EventDispatchExtensions/DragEventDispatchExtensionsTest.cs diff --git a/tests/bunit.web.tests/EventDispatchExtensions/EventDispatchExtensionsTest.cs b/tests/bunit.tests/EventDispatchExtensions/EventDispatchExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/EventDispatchExtensions/EventDispatchExtensionsTest.cs rename to tests/bunit.tests/EventDispatchExtensions/EventDispatchExtensionsTest.cs diff --git a/tests/bunit.web.tests/EventDispatchExtensions/FocusEventDispatchExtensionsTest.cs b/tests/bunit.tests/EventDispatchExtensions/FocusEventDispatchExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/EventDispatchExtensions/FocusEventDispatchExtensionsTest.cs rename to tests/bunit.tests/EventDispatchExtensions/FocusEventDispatchExtensionsTest.cs diff --git a/tests/bunit.web.tests/EventDispatchExtensions/GeneralEventDispatchExtensionsTest.cs b/tests/bunit.tests/EventDispatchExtensions/GeneralEventDispatchExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/EventDispatchExtensions/GeneralEventDispatchExtensionsTest.cs rename to tests/bunit.tests/EventDispatchExtensions/GeneralEventDispatchExtensionsTest.cs diff --git a/tests/bunit.web.tests/EventDispatchExtensions/InputEventDispatchExtensionsTest.cs b/tests/bunit.tests/EventDispatchExtensions/InputEventDispatchExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/EventDispatchExtensions/InputEventDispatchExtensionsTest.cs rename to tests/bunit.tests/EventDispatchExtensions/InputEventDispatchExtensionsTest.cs diff --git a/tests/bunit.web.tests/EventDispatchExtensions/KeyTest.cs b/tests/bunit.tests/EventDispatchExtensions/KeyTest.cs similarity index 100% rename from tests/bunit.web.tests/EventDispatchExtensions/KeyTest.cs rename to tests/bunit.tests/EventDispatchExtensions/KeyTest.cs diff --git a/tests/bunit.web.tests/EventDispatchExtensions/KeyboardEventDispatchExtensionsTest.cs b/tests/bunit.tests/EventDispatchExtensions/KeyboardEventDispatchExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/EventDispatchExtensions/KeyboardEventDispatchExtensionsTest.cs rename to tests/bunit.tests/EventDispatchExtensions/KeyboardEventDispatchExtensionsTest.cs diff --git a/tests/bunit.web.tests/EventDispatchExtensions/MediaEventDispatchExtensionsTest.cs b/tests/bunit.tests/EventDispatchExtensions/MediaEventDispatchExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/EventDispatchExtensions/MediaEventDispatchExtensionsTest.cs rename to tests/bunit.tests/EventDispatchExtensions/MediaEventDispatchExtensionsTest.cs diff --git a/tests/bunit.web.tests/EventDispatchExtensions/MouseEventDispatchExtensionsTest.cs b/tests/bunit.tests/EventDispatchExtensions/MouseEventDispatchExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/EventDispatchExtensions/MouseEventDispatchExtensionsTest.cs rename to tests/bunit.tests/EventDispatchExtensions/MouseEventDispatchExtensionsTest.cs diff --git a/tests/bunit.web.tests/EventDispatchExtensions/PointerEventDispatchExtensionsTest.cs b/tests/bunit.tests/EventDispatchExtensions/PointerEventDispatchExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/EventDispatchExtensions/PointerEventDispatchExtensionsTest.cs rename to tests/bunit.tests/EventDispatchExtensions/PointerEventDispatchExtensionsTest.cs diff --git a/tests/bunit.web.tests/EventDispatchExtensions/ProgressEventDispatchExtensionsTest.cs b/tests/bunit.tests/EventDispatchExtensions/ProgressEventDispatchExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/EventDispatchExtensions/ProgressEventDispatchExtensionsTest.cs rename to tests/bunit.tests/EventDispatchExtensions/ProgressEventDispatchExtensionsTest.cs diff --git a/tests/bunit.web.tests/EventDispatchExtensions/TouchEventDispatchExtensionsTest.cs b/tests/bunit.tests/EventDispatchExtensions/TouchEventDispatchExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/EventDispatchExtensions/TouchEventDispatchExtensionsTest.cs rename to tests/bunit.tests/EventDispatchExtensions/TouchEventDispatchExtensionsTest.cs diff --git a/tests/bunit.web.tests/EventDispatchExtensions/TriggerEventSpy.cs b/tests/bunit.tests/EventDispatchExtensions/TriggerEventSpy.cs similarity index 100% rename from tests/bunit.web.tests/EventDispatchExtensions/TriggerEventSpy.cs rename to tests/bunit.tests/EventDispatchExtensions/TriggerEventSpy.cs diff --git a/tests/bunit.web.tests/EventDispatchExtensions/WheelEventDispatchExtensionsTest.cs b/tests/bunit.tests/EventDispatchExtensions/WheelEventDispatchExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/EventDispatchExtensions/WheelEventDispatchExtensionsTest.cs rename to tests/bunit.tests/EventDispatchExtensions/WheelEventDispatchExtensionsTest.cs diff --git a/tests/bunit.web.tests/Extensions/InputFile/InputFileTests.cs b/tests/bunit.tests/Extensions/InputFile/InputFileTests.cs similarity index 100% rename from tests/bunit.web.tests/Extensions/InputFile/InputFileTests.cs rename to tests/bunit.tests/Extensions/InputFile/InputFileTests.cs diff --git a/tests/bunit.web.tests/Extensions/RefreshableQueryCollectionTest.cs b/tests/bunit.tests/Extensions/RefreshableQueryCollectionTest.cs similarity index 100% rename from tests/bunit.web.tests/Extensions/RefreshableQueryCollectionTest.cs rename to tests/bunit.tests/Extensions/RefreshableQueryCollectionTest.cs diff --git a/tests/bunit.web.tests/Extensions/RefreshingWrappedElementTest.cs b/tests/bunit.tests/Extensions/RefreshingWrappedElementTest.cs similarity index 100% rename from tests/bunit.web.tests/Extensions/RefreshingWrappedElementTest.cs rename to tests/bunit.tests/Extensions/RefreshingWrappedElementTest.cs diff --git a/tests/bunit.core.tests/Extensions/RenderedComponentRenderExtensionsTest.cs b/tests/bunit.tests/Extensions/RenderedComponentRenderExtensionsTest.cs similarity index 100% rename from tests/bunit.core.tests/Extensions/RenderedComponentRenderExtensionsTest.cs rename to tests/bunit.tests/Extensions/RenderedComponentRenderExtensionsTest.cs diff --git a/tests/bunit.web.tests/Extensions/WaitForHelpers/RenderedFragmentWaitForElementsHelperExtensions.Async.Test.cs b/tests/bunit.tests/Extensions/WaitForHelpers/RenderedFragmentWaitForElementsHelperExtensions.Async.Test.cs similarity index 100% rename from tests/bunit.web.tests/Extensions/WaitForHelpers/RenderedFragmentWaitForElementsHelperExtensions.Async.Test.cs rename to tests/bunit.tests/Extensions/WaitForHelpers/RenderedFragmentWaitForElementsHelperExtensions.Async.Test.cs diff --git a/tests/bunit.web.tests/Extensions/WaitForHelpers/RenderedFragmentWaitForElementsHelperExtensionsTest.cs b/tests/bunit.tests/Extensions/WaitForHelpers/RenderedFragmentWaitForElementsHelperExtensionsTest.cs similarity index 100% rename from tests/bunit.web.tests/Extensions/WaitForHelpers/RenderedFragmentWaitForElementsHelperExtensionsTest.cs rename to tests/bunit.tests/Extensions/WaitForHelpers/RenderedFragmentWaitForElementsHelperExtensionsTest.cs diff --git a/tests/bunit.core.tests/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensionsTest.cs b/tests/bunit.tests/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensionsTest.cs similarity index 100% rename from tests/bunit.core.tests/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensionsTest.cs rename to tests/bunit.tests/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensionsTest.cs diff --git a/tests/bunit.web.tests/JSInterop/BunitJSInteropTest.cs b/tests/bunit.tests/JSInterop/BunitJSInteropTest.cs similarity index 100% rename from tests/bunit.web.tests/JSInterop/BunitJSInteropTest.cs rename to tests/bunit.tests/JSInterop/BunitJSInteropTest.cs diff --git a/tests/bunit.web.tests/JSInterop/BunitJSInteropTest.net5.cs b/tests/bunit.tests/JSInterop/BunitJSInteropTest.net5.cs similarity index 100% rename from tests/bunit.web.tests/JSInterop/BunitJSInteropTest.net5.cs rename to tests/bunit.tests/JSInterop/BunitJSInteropTest.net5.cs diff --git a/tests/bunit.web.tests/JSInterop/BunitJSObjectReferenceTest.cs b/tests/bunit.tests/JSInterop/BunitJSObjectReferenceTest.cs similarity index 100% rename from tests/bunit.web.tests/JSInterop/BunitJSObjectReferenceTest.cs rename to tests/bunit.tests/JSInterop/BunitJSObjectReferenceTest.cs diff --git a/tests/bunit.web.tests/JSInterop/InvocationHandlers/FocusAsyncInvocationHandlerTest.cs b/tests/bunit.tests/JSInterop/InvocationHandlers/FocusAsyncInvocationHandlerTest.cs similarity index 100% rename from tests/bunit.web.tests/JSInterop/InvocationHandlers/FocusAsyncInvocationHandlerTest.cs rename to tests/bunit.tests/JSInterop/InvocationHandlers/FocusAsyncInvocationHandlerTest.cs diff --git a/tests/bunit.web.tests/JSInterop/InvocationHandlers/FocusOnNavigateHandlerTest.cs b/tests/bunit.tests/JSInterop/InvocationHandlers/FocusOnNavigateHandlerTest.cs similarity index 100% rename from tests/bunit.web.tests/JSInterop/InvocationHandlers/FocusOnNavigateHandlerTest.cs rename to tests/bunit.tests/JSInterop/InvocationHandlers/FocusOnNavigateHandlerTest.cs diff --git a/tests/bunit.web.tests/JSInterop/InvocationHandlers/VirtualizeJSRuntimeInvocationHandlerTest.cs b/tests/bunit.tests/JSInterop/InvocationHandlers/VirtualizeJSRuntimeInvocationHandlerTest.cs similarity index 100% rename from tests/bunit.web.tests/JSInterop/InvocationHandlers/VirtualizeJSRuntimeInvocationHandlerTest.cs rename to tests/bunit.tests/JSInterop/InvocationHandlers/VirtualizeJSRuntimeInvocationHandlerTest.cs diff --git a/tests/bunit.web.tests/JSInterop/JSRuntimeInvocationTest.cs b/tests/bunit.tests/JSInterop/JSRuntimeInvocationTest.cs similarity index 100% rename from tests/bunit.web.tests/JSInterop/JSRuntimeInvocationTest.cs rename to tests/bunit.tests/JSInterop/JSRuntimeInvocationTest.cs diff --git a/tests/bunit.web.tests/JSInterop/JSRuntimeUnhandledInvocationExceptionTest.cs b/tests/bunit.tests/JSInterop/JSRuntimeUnhandledInvocationExceptionTest.cs similarity index 100% rename from tests/bunit.web.tests/JSInterop/JSRuntimeUnhandledInvocationExceptionTest.cs rename to tests/bunit.tests/JSInterop/JSRuntimeUnhandledInvocationExceptionTest.cs diff --git a/tests/bunit.web.tests/JSInterop/JSRuntimeUnhandledInvocationExceptionTest.net5.cs b/tests/bunit.tests/JSInterop/JSRuntimeUnhandledInvocationExceptionTest.net5.cs similarity index 100% rename from tests/bunit.web.tests/JSInterop/JSRuntimeUnhandledInvocationExceptionTest.net5.cs rename to tests/bunit.tests/JSInterop/JSRuntimeUnhandledInvocationExceptionTest.net5.cs diff --git a/tests/bunit.core.tests/Rendering/BunitComponentActivatorTest.cs b/tests/bunit.tests/Rendering/BunitComponentActivatorTest.cs similarity index 100% rename from tests/bunit.core.tests/Rendering/BunitComponentActivatorTest.cs rename to tests/bunit.tests/Rendering/BunitComponentActivatorTest.cs diff --git a/tests/bunit.web.tests/Rendering/BunitHtmlParserTest.cs b/tests/bunit.tests/Rendering/BunitHtmlParserTest.cs similarity index 100% rename from tests/bunit.web.tests/Rendering/BunitHtmlParserTest.cs rename to tests/bunit.tests/Rendering/BunitHtmlParserTest.cs diff --git a/tests/bunit.core.tests/Rendering/ComponentParameterTest.cs b/tests/bunit.tests/Rendering/ComponentParameterTest.cs similarity index 100% rename from tests/bunit.core.tests/Rendering/ComponentParameterTest.cs rename to tests/bunit.tests/Rendering/ComponentParameterTest.cs diff --git a/tests/bunit.web.tests/Rendering/Internal/HtmlizerTests.cs b/tests/bunit.tests/Rendering/Internal/HtmlizerTests.cs similarity index 100% rename from tests/bunit.web.tests/Rendering/Internal/HtmlizerTests.cs rename to tests/bunit.tests/Rendering/Internal/HtmlizerTests.cs diff --git a/tests/bunit.web.tests/Rendering/Internal/HtmlizerTests.net5.cs b/tests/bunit.tests/Rendering/Internal/HtmlizerTests.net5.cs similarity index 100% rename from tests/bunit.web.tests/Rendering/Internal/HtmlizerTests.net5.cs rename to tests/bunit.tests/Rendering/Internal/HtmlizerTests.net5.cs diff --git a/tests/bunit.web.tests/Rendering/RenderedComponentTest.cs b/tests/bunit.tests/Rendering/RenderedComponentTest.cs similarity index 100% rename from tests/bunit.web.tests/Rendering/RenderedComponentTest.cs rename to tests/bunit.tests/Rendering/RenderedComponentTest.cs diff --git a/tests/bunit.web.tests/Rendering/RenderedFragmentTest.cs b/tests/bunit.tests/Rendering/RenderedFragmentTest.cs similarity index 100% rename from tests/bunit.web.tests/Rendering/RenderedFragmentTest.cs rename to tests/bunit.tests/Rendering/RenderedFragmentTest.cs diff --git a/tests/bunit.core.tests/Rendering/RootRenderTreeTest.cs b/tests/bunit.tests/Rendering/RootRenderTreeTest.cs similarity index 100% rename from tests/bunit.core.tests/Rendering/RootRenderTreeTest.cs rename to tests/bunit.tests/Rendering/RootRenderTreeTest.cs diff --git a/tests/bunit.core.tests/Rendering/TestRendererTest.cs b/tests/bunit.tests/Rendering/TestRendererTest.cs similarity index 100% rename from tests/bunit.core.tests/Rendering/TestRendererTest.cs rename to tests/bunit.tests/Rendering/TestRendererTest.cs diff --git a/tests/bunit.core.tests/Rendering/TestRendererTest.net5.cs b/tests/bunit.tests/Rendering/TestRendererTest.net5.cs similarity index 100% rename from tests/bunit.core.tests/Rendering/TestRendererTest.net5.cs rename to tests/bunit.tests/Rendering/TestRendererTest.net5.cs diff --git a/tests/bunit.core.tests/ShouldlyExtensions.cs b/tests/bunit.tests/ShouldlyExtensions.cs similarity index 100% rename from tests/bunit.core.tests/ShouldlyExtensions.cs rename to tests/bunit.tests/ShouldlyExtensions.cs diff --git a/tests/bunit.core.tests/TestContextBaseTest.cs b/tests/bunit.tests/TestContextBaseTest.cs similarity index 100% rename from tests/bunit.core.tests/TestContextBaseTest.cs rename to tests/bunit.tests/TestContextBaseTest.cs diff --git a/tests/bunit.core.tests/TestContextBaseTest.net5.cs b/tests/bunit.tests/TestContextBaseTest.net5.cs similarity index 100% rename from tests/bunit.core.tests/TestContextBaseTest.net5.cs rename to tests/bunit.tests/TestContextBaseTest.net5.cs diff --git a/tests/bunit.web.tests/TestContextTest.cs b/tests/bunit.tests/TestContextTest.cs similarity index 100% rename from tests/bunit.web.tests/TestContextTest.cs rename to tests/bunit.tests/TestContextTest.cs diff --git a/tests/bunit.web.tests/TestContextTest.net6.cs b/tests/bunit.tests/TestContextTest.net6.cs similarity index 100% rename from tests/bunit.web.tests/TestContextTest.net6.cs rename to tests/bunit.tests/TestContextTest.net6.cs diff --git a/tests/bunit.web.tests/TestDoubles/Authorization/AuthorizationTest.cs b/tests/bunit.tests/TestDoubles/Authorization/AuthorizationTest.cs similarity index 100% rename from tests/bunit.web.tests/TestDoubles/Authorization/AuthorizationTest.cs rename to tests/bunit.tests/TestDoubles/Authorization/AuthorizationTest.cs diff --git a/tests/bunit.web.tests/TestDoubles/Authorization/FakeAuthenticationStateProviderTest.cs b/tests/bunit.tests/TestDoubles/Authorization/FakeAuthenticationStateProviderTest.cs similarity index 100% rename from tests/bunit.web.tests/TestDoubles/Authorization/FakeAuthenticationStateProviderTest.cs rename to tests/bunit.tests/TestDoubles/Authorization/FakeAuthenticationStateProviderTest.cs diff --git a/tests/bunit.web.tests/TestDoubles/Authorization/FakeAuthorizationPolicyProviderTest.cs b/tests/bunit.tests/TestDoubles/Authorization/FakeAuthorizationPolicyProviderTest.cs similarity index 100% rename from tests/bunit.web.tests/TestDoubles/Authorization/FakeAuthorizationPolicyProviderTest.cs rename to tests/bunit.tests/TestDoubles/Authorization/FakeAuthorizationPolicyProviderTest.cs diff --git a/tests/bunit.web.tests/TestDoubles/Authorization/FakeAuthorizationServiceTest.cs b/tests/bunit.tests/TestDoubles/Authorization/FakeAuthorizationServiceTest.cs similarity index 100% rename from tests/bunit.web.tests/TestDoubles/Authorization/FakeAuthorizationServiceTest.cs rename to tests/bunit.tests/TestDoubles/Authorization/FakeAuthorizationServiceTest.cs diff --git a/tests/bunit.web.tests/TestDoubles/Authorization/TestAuthorizationContextTest.cs b/tests/bunit.tests/TestDoubles/Authorization/TestAuthorizationContextTest.cs similarity index 100% rename from tests/bunit.web.tests/TestDoubles/Authorization/TestAuthorizationContextTest.cs rename to tests/bunit.tests/TestDoubles/Authorization/TestAuthorizationContextTest.cs diff --git a/tests/bunit.web.tests/TestDoubles/Components/CapturedParameterViewTest.cs b/tests/bunit.tests/TestDoubles/Components/CapturedParameterViewTest.cs similarity index 100% rename from tests/bunit.web.tests/TestDoubles/Components/CapturedParameterViewTest.cs rename to tests/bunit.tests/TestDoubles/Components/CapturedParameterViewTest.cs diff --git a/tests/bunit.web.tests/TestDoubles/Components/ComponentDoubleBaseTest.cs b/tests/bunit.tests/TestDoubles/Components/ComponentDoubleBaseTest.cs similarity index 100% rename from tests/bunit.web.tests/TestDoubles/Components/ComponentDoubleBaseTest.cs rename to tests/bunit.tests/TestDoubles/Components/ComponentDoubleBaseTest.cs diff --git a/tests/bunit.web.tests/TestDoubles/Components/StubTest.cs b/tests/bunit.tests/TestDoubles/Components/StubTest.cs similarity index 100% rename from tests/bunit.web.tests/TestDoubles/Components/StubTest.cs rename to tests/bunit.tests/TestDoubles/Components/StubTest.cs diff --git a/tests/bunit.web.tests/TestDoubles/FakeSignOutSessionStateManagerTest.cs b/tests/bunit.tests/TestDoubles/FakeSignOutSessionStateManagerTest.cs similarity index 100% rename from tests/bunit.web.tests/TestDoubles/FakeSignOutSessionStateManagerTest.cs rename to tests/bunit.tests/TestDoubles/FakeSignOutSessionStateManagerTest.cs diff --git a/tests/bunit.web.tests/TestDoubles/FakeWebAssemblyHostEnvironmentTest.cs b/tests/bunit.tests/TestDoubles/FakeWebAssemblyHostEnvironmentTest.cs similarity index 100% rename from tests/bunit.web.tests/TestDoubles/FakeWebAssemblyHostEnvironmentTest.cs rename to tests/bunit.tests/TestDoubles/FakeWebAssemblyHostEnvironmentTest.cs diff --git a/tests/bunit.web.tests/TestDoubles/NavigationManager/FakeNavigationInterceptionTest.cs b/tests/bunit.tests/TestDoubles/NavigationManager/FakeNavigationInterceptionTest.cs similarity index 100% rename from tests/bunit.web.tests/TestDoubles/NavigationManager/FakeNavigationInterceptionTest.cs rename to tests/bunit.tests/TestDoubles/NavigationManager/FakeNavigationInterceptionTest.cs diff --git a/tests/bunit.web.tests/TestDoubles/NavigationManager/FakeNavigationManagerTest.cs b/tests/bunit.tests/TestDoubles/NavigationManager/FakeNavigationManagerTest.cs similarity index 100% rename from tests/bunit.web.tests/TestDoubles/NavigationManager/FakeNavigationManagerTest.cs rename to tests/bunit.tests/TestDoubles/NavigationManager/FakeNavigationManagerTest.cs diff --git a/tests/bunit.core.tests/TestDoubles/PersistentComponentState/FakePersistentComponentStateTest.cs b/tests/bunit.tests/TestDoubles/PersistentComponentState/FakePersistentComponentStateTest.cs similarity index 100% rename from tests/bunit.core.tests/TestDoubles/PersistentComponentState/FakePersistentComponentStateTest.cs rename to tests/bunit.tests/TestDoubles/PersistentComponentState/FakePersistentComponentStateTest.cs diff --git a/tests/bunit.core.tests/TestServiceProviderTest.cs b/tests/bunit.tests/TestServiceProviderTest.cs similarity index 100% rename from tests/bunit.core.tests/TestServiceProviderTest.cs rename to tests/bunit.tests/TestServiceProviderTest.cs diff --git a/tests/bunit.web.tests/TestUtilities/JSRuntimeInvocationAssertionHelpers.cs b/tests/bunit.tests/TestUtilities/JSRuntimeInvocationAssertionHelpers.cs similarity index 100% rename from tests/bunit.web.tests/TestUtilities/JSRuntimeInvocationAssertionHelpers.cs rename to tests/bunit.tests/TestUtilities/JSRuntimeInvocationAssertionHelpers.cs diff --git a/tests/bunit.web.tests/TestUtilities/MockingHelpers.cs b/tests/bunit.tests/TestUtilities/MockingHelpers.cs similarity index 100% rename from tests/bunit.web.tests/TestUtilities/MockingHelpers.cs rename to tests/bunit.tests/TestUtilities/MockingHelpers.cs diff --git a/tests/bunit.core.tests/_Imports.razor b/tests/bunit.tests/_Imports.razor similarity index 100% rename from tests/bunit.core.tests/_Imports.razor rename to tests/bunit.tests/_Imports.razor diff --git a/tests/bunit.core.tests/bunit.core.tests.csproj b/tests/bunit.tests/bunit.tests.csproj similarity index 78% rename from tests/bunit.core.tests/bunit.core.tests.csproj rename to tests/bunit.tests/bunit.tests.csproj index 9e4606b8a..5ef48245c 100644 --- a/tests/bunit.core.tests/bunit.core.tests.csproj +++ b/tests/bunit.tests/bunit.tests.csproj @@ -3,12 +3,11 @@ net8.0;net9.0 Bunit - Bunit.Core.Tests + Bunit.Tests - - + diff --git a/tests/bunit.core.tests/xunit.runner.json b/tests/bunit.tests/xunit.runner.json similarity index 100% rename from tests/bunit.core.tests/xunit.runner.json rename to tests/bunit.tests/xunit.runner.json diff --git a/tests/bunit.web.query.tests/bunit.web.query.tests.csproj b/tests/bunit.web.query.tests/bunit.web.query.tests.csproj index 17fdd9828..264b075d5 100644 --- a/tests/bunit.web.query.tests/bunit.web.query.tests.csproj +++ b/tests/bunit.web.query.tests/bunit.web.query.tests.csproj @@ -7,8 +7,7 @@ - - + diff --git a/tests/bunit.web.tests/bunit.web.tests.csproj b/tests/bunit.web.tests/bunit.web.tests.csproj deleted file mode 100644 index 55c54e4f8..000000000 --- a/tests/bunit.web.tests/bunit.web.tests.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - net8.0;net9.0 - Bunit - Bunit.Web.Tests - - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers - NU1701 - - - - \ No newline at end of file diff --git a/tests/bunit.web.tests/xunit.runner.json b/tests/bunit.web.tests/xunit.runner.json deleted file mode 100644 index e37151e81..000000000 --- a/tests/bunit.web.tests/xunit.runner.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", - "diagnosticMessages": false -} From 8468c6871fde889df56935ef586f6dd757e08299 Mon Sep 17 00:00:00 2001 From: Steven Giesel Date: Sun, 7 May 2023 22:27:25 +0200 Subject: [PATCH 07/42] feat: Remove unused abstraction --- MIGRATION.md | 8 ++++ .../docs/interaction/awaiting-async-state.md | 4 +- .../docs/interaction/dispose-components.md | 2 +- docs/site/docs/interaction/trigger-renders.md | 16 ++++---- .../site/docs/verification/async-assertion.md | 4 +- .../verification/verify-component-state.md | 8 ++-- src/bunit/Asserting/CompareToExtensions.cs | 6 +-- .../MarkupMatchesAssertExtensions.cs | 4 +- ...actory{TComponent,TSubstituteComponent}.cs | 4 +- .../ComponentFactoryCollectionExtensions.cs | 2 +- .../IRefreshableElementCollection.cs | 4 +- .../RenderedComponentRenderExtensions.cs | 10 ++--- .../Extensions/RenderedFragmentExtensions.cs | 2 +- .../RenderedFragmentInvokeAsyncExtensions.cs | 10 ++--- .../TestContextBaseRenderExtensions.cs | 8 ++-- .../TestServiceProviderExtensions.cs | 2 +- ...entWaitForHelperExtensions.WaitForState.cs | 8 ++-- .../WaitForHelpers/WaitForAssertionHelper.cs | 2 +- .../WaitForHelpers/WaitForHelper.cs | 6 +-- .../WaitForHelpers/WaitForStateHelper.cs | 2 +- src/bunit/IRenderedComponent.cs | 6 ++- src/bunit/IRenderedComponentBase.cs | 14 ------- src/bunit/IRenderedFragment.cs | 36 +++++++++++++++-- src/bunit/IRenderedFragmentBase.cs | 40 ------------------- .../Rendering/ComponentDisposedException.cs | 2 +- .../Rendering/IRenderedComponentActivator.cs | 14 +++---- src/bunit/Rendering/ITestRenderer.cs | 12 +++--- src/bunit/Rendering/RenderEvent.cs | 2 +- .../Rendering/RenderedComponentActivator.cs | 6 +-- src/bunit/Rendering/RenderedFragment.cs | 2 +- src/bunit/Rendering/TestRenderer.cs | 28 +++++++------ src/bunit/Rendering/WebTestRenderer.cs | 28 ------------- src/bunit/TestContext.cs | 8 ++-- src/bunit/TestContextBase.cs | 2 +- ...omponentParameterCollectionBuilderTests.cs | 4 +- .../ComponentParameterCollectionTest.cs | 2 +- .../ComponentParameterFactoryTest.cs | 2 +- .../bunit.tests/Rendering/TestRendererTest.cs | 20 +++++----- 38 files changed, 151 insertions(+), 189 deletions(-) delete mode 100644 src/bunit/IRenderedComponentBase.cs delete mode 100644 src/bunit/IRenderedFragmentBase.cs delete mode 100644 src/bunit/Rendering/WebTestRenderer.cs diff --git a/MIGRATION.md b/MIGRATION.md index 142d55daa..fa9dd9e0d 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -25,3 +25,11 @@ public static class Extensions ## Merge of `bunit.core` and `bunit.web` The `bunit.core` and `bunit.web` packages have been merged into a single `bunit` package. If you used either of these packages, you should remove them and install the `bunit` package instead. + +## Removal of unneeded abstraction + +### `IRenderedComponentBase` and `IRenderedFragmentBase` +`IRenderedComponentBase` and `IRenderedFragmentBase` have been removed. They were used to provide a common base class for `IRenderedComponent` and `IRenderedFragment`, but this is no longer needed (due to the merge of the project). If you used either of these interfaces, you should replace them with `IRenderedComponent` and `IRenderedFragment` respectively. + +### `WebTestRender` merged into `TestRender` +The `WebTestRender` class has been merged into the `TestRender` class. If you used `WebTestRender`, you should replace it with `TestRender`. diff --git a/docs/site/docs/interaction/awaiting-async-state.md b/docs/site/docs/interaction/awaiting-async-state.md index d852df40f..2d7c668af 100644 --- a/docs/site/docs/interaction/awaiting-async-state.md +++ b/docs/site/docs/interaction/awaiting-async-state.md @@ -9,13 +9,13 @@ A test can fail if a component performs asynchronous renders. This may be due to You need to handle this specifically in your tests because tests execute in the test framework's synchronization context and the test renderer executes renders in its own synchronization context. If you do not, you will likely experience tests that sometimes pass and sometimes fail. -bUnit comes with two methods that help to deal with this issue: the [`WaitForState()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForState(Bunit.IRenderedFragmentBase,System.Func{System.Boolean},System.Nullable{System.TimeSpan})) method covered on this page, and the [`WaitForAssertion()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForAssertion(Bunit.IRenderedFragmentBase,System.Action,System.Nullable{System.TimeSpan})) method covered on the page. +bUnit comes with two methods that help to deal with this issue: the [`WaitForState()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForState(Bunit.IRenderedFragment,Func{System.Boolean},System.Nullable{TimeSpan})) method covered on this page, and the [`WaitForAssertion()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForAssertion(Bunit.IRenderedFragment,Action,System.Nullable{TimeSpan})) method covered on the page. Let's start by taking a look at the `WaitForState` method in more detail. ## Waiting for state using `WaitForState` -The [`WaitForState(Func, TimeSpan?)`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForState(Bunit.IRenderedFragmentBase,System.Func{System.Boolean},System.Nullable{System.TimeSpan})) method can be used to block and wait in a test method, until the provided predicate returns true or the timeout is reached. (The default timeout is one second.) +The [`WaitForState(Func, TimeSpan?)`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForState(Bunit.IRenderedFragment,Func{System.Boolean},System.Nullable{TimeSpan})) method can be used to block and wait in a test method, until the provided predicate returns true or the timeout is reached. (The default timeout is one second.) > [!NOTE] > The `WaitForState()` method will try the predicate passed to it when the `WaitForState()` method is called, and every time the component under test renders. diff --git a/docs/site/docs/interaction/dispose-components.md b/docs/site/docs/interaction/dispose-components.md index b0517603d..8995d9e94 100644 --- a/docs/site/docs/interaction/dispose-components.md +++ b/docs/site/docs/interaction/dispose-components.md @@ -13,7 +13,7 @@ The following example of this: [!code-csharp[](../../../samples/tests/xunit/DisposeComponentsTest.cs#L13-L22)] > [!WARNING] -> For `IAsyncDisposable` (since .net5) relying on [`WaitForState()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForState(Bunit.IRenderedFragmentBase,System.Func{System.Boolean},System.Nullable{System.TimeSpan})) or [`WaitForAssertion()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForAssertion(Bunit.IRenderedFragmentBase,System.Action,System.Nullable{System.TimeSpan})) will not work as a disposed component will not trigger a new render cycle. +> For `IAsyncDisposable` (since .net5) relying on [`WaitForState()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForState(Bunit.IRenderedFragment,Func{System.Boolean},System.Nullable{TimeSpan})) or [`WaitForAssertion()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForAssertion(Bunit.IRenderedFragment,Action,System.Nullable{TimeSpan})) will not work as a disposed component will not trigger a new render cycle. ## Checking for exceptions `Dispose` as well as `DisposeAsync` can throw exceptions which can be asserted as well. If a component under test throws an exception in `Dispose` the [`DisposeComponents`](xref:Bunit.TestContextBase.DisposeComponents) will throw the exception to the user code: diff --git a/docs/site/docs/interaction/trigger-renders.md b/docs/site/docs/interaction/trigger-renders.md index da2b35253..ed60a9e67 100644 --- a/docs/site/docs/interaction/trigger-renders.md +++ b/docs/site/docs/interaction/trigger-renders.md @@ -11,31 +11,31 @@ In `.razor` based tests, using the 's or a in a test, but need a child component's , then use the `FindComponent()` or the `FindComponents()` methods, which traverse down the render tree and finds rendered components. -With a , it is possible to cause the component to render again directly through the [`Render()`](xref:Bunit.TestContext.Render``1(Microsoft.AspNetCore.Components.RenderFragment)) method or one of the [`SetParametersAndRender()`](xref:Bunit.RenderedComponentRenderExtensions.SetParametersAndRender``1(Bunit.IRenderedComponentBase{``0},System.Action{Bunit.ComponentParameterCollectionBuilder{``0}})) methods, or indirectly through the [`InvokeAsync()`](xref:Bunit.IRenderedFragmentBase.Bunit.RenderedFragmentInvokeAsyncExtensions.InvokeAsync(System.Action)) method. +With a , it is possible to cause the component to render again directly through the [`Render()`](xref:Bunit.TestContext.Render``1(Microsoft.AspNetCore.Components.RenderFragment)) method or one of the [`SetParametersAndRender()`](xref:Bunit.RenderedComponentRenderExtensions.SetParametersAndRender``1(Bunit.IRenderedComponent{``0},System.Action{Bunit.ComponentParameterCollectionBuilder{``0}})) methods, or indirectly through the [`InvokeAsync()`](xref:Bunit.IRenderedFragment.Bunit.RenderedFragmentInvokeAsyncExtensions.InvokeAsync(System.Action)) method. Let's look at how to use each of these methods to cause a re-render. ## Render -The [`Render()`](xref:Bunit.RenderedComponentRenderExtensions.Render``1(Bunit.IRenderedComponentBase{``0})) method tells the renderer to re-render the component, i.e. go through its life-cycle methods (except for `OnInitialized()` and `OnInitializedAsync()` methods). To use it, do the following: +The [`Render()`](xref:Bunit.RenderedComponentRenderExtensions.Render``1(Bunit.IRenderedComponent{``0})) method tells the renderer to re-render the component, i.e. go through its life-cycle methods (except for `OnInitialized()` and `OnInitializedAsync()` methods). To use it, do the following: [!code-csharp[](../../../samples/tests/xunit/ReRenderTest.cs?start=16&end=22&highlight=5)] -The highlighted line shows the call to [`Render()`](xref:Bunit.RenderedComponentRenderExtensions.Render``1(Bunit.IRenderedComponentBase{``0})). +The highlighted line shows the call to [`Render()`](xref:Bunit.RenderedComponentRenderExtensions.Render``1(Bunit.IRenderedComponent{``0})). > [!TIP] -> The number of renders a component has been through can be inspected and verified using the property. +> The number of renders a component has been through can be inspected and verified using the property. ## SetParametersAndRender -The [`SetParametersAndRender(...)`](xref:Bunit.RenderedComponentRenderExtensions.SetParametersAndRender``1(Bunit.IRenderedComponentBase{``0},System.Action{Bunit.ComponentParameterCollectionBuilder{``0}})) methods tells the renderer to re-render the component with new parameters, i.e. go through its life-cycle methods (except for `OnInitialized()` and `OnInitializedAsync()` methods), passing the new parameters — _but only the new parameters_ — to the `SetParametersAsync()` method. To use it, do the following: +The [`SetParametersAndRender(...)`](xref:Bunit.RenderedComponentRenderExtensions.SetParametersAndRender``1(Bunit.IRenderedComponent{``0},Action{Bunit.ComponentParameterCollectionBuilder{``0}})) methods tells the renderer to re-render the component with new parameters, i.e. go through its life-cycle methods (except for `OnInitialized()` and `OnInitializedAsync()` methods), passing the new parameters — _but only the new parameters_ — to the `SetParametersAsync()` method. To use it, do the following: [!code-csharp[](../../../samples/tests/xunit/ReRenderTest.cs?start=29&end=39&highlight=7-9)] -The highlighted line shows the call to [`SetParametersAndRender()`](xref:Bunit.RenderedComponentRenderExtensions.SetParametersAndRender``1(Bunit.IRenderedComponentBase{``0},System.Action{Bunit.ComponentParameterCollectionBuilder{``0}})), which is also available as a version that takes the zero or more component parameters, e.g. created through the component parameter factory helper methods, if you prefer that method of passing parameters. +The highlighted line shows the call to [`SetParametersAndRender()`](xref:Bunit.RenderedComponentRenderExtensions.SetParametersAndRender``1(Bunit.IRenderedComponent{``0},Action{Bunit.ComponentParameterCollectionBuilder{``0}})), which is also available as a version that takes the zero or more component parameters, e.g. created through the component parameter factory helper methods, if you prefer that method of passing parameters. > [!NOTE] -> Passing parameters to components through the [`SetParametersAndRender(...)`](xref:Bunit.RenderedComponentRenderExtensions.SetParametersAndRender``1(Bunit.IRenderedComponentBase{``0},System.Action{Bunit.ComponentParameterCollectionBuilder{``0}})) methods is identical to doing it with the `RenderComponent(...)` methods, described in detail on the page. +> Passing parameters to components through the [`SetParametersAndRender(...)`](xref:Bunit.RenderedComponentRenderExtensions.SetParametersAndRender``1(Bunit.IRenderedComponent{``0},Action{Bunit.ComponentParameterCollectionBuilder{``0}})) methods is identical to doing it with the `RenderComponent(...)` methods, described in detail on the page. ## InvokeAsync @@ -72,4 +72,4 @@ This can also be used to assert intermediate states during an asynchronous opera [!code-cshtml[CalcWithLoading.razor](../../../samples/components/CalcWithLoading.razor)] -[!code-csharp[](../../../samples/tests/xunit/ReRenderTest.cs?start=71&end=82&highlight=7)] \ No newline at end of file +[!code-csharp[](../../../samples/tests/xunit/ReRenderTest.cs?start=71&end=82&highlight=7)] diff --git a/docs/site/docs/verification/async-assertion.md b/docs/site/docs/verification/async-assertion.md index 3a4f45a4f..4f37ef4a2 100644 --- a/docs/site/docs/verification/async-assertion.md +++ b/docs/site/docs/verification/async-assertion.md @@ -9,13 +9,13 @@ A test can fail if a component performs asynchronous renders. This may be due to You need to handle this specifically in your tests because tests execute in the test framework's synchronization context and the test renderer executes renders in its own synchronization context. If you do not, you will likely experience tests that sometimes pass, and sometimes fail. -bUnit comes with two methods that help to deal with this issue: the [`WaitForAssertion()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForAssertion(Bunit.IRenderedFragmentBase,System.Action,System.Nullable{System.TimeSpan})) method covered on this page, and the [`WaitForState()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForState(Bunit.IRenderedFragmentBase,System.Func{System.Boolean},System.Nullable{System.TimeSpan})) method covered on the page. +bUnit comes with two methods that help to deal with this issue: the [`WaitForAssertion()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForAssertion(Bunit.IRenderedFragment,Action,System.Nullable{TimeSpan})) method covered on this page, and the [`WaitForState()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForState(Bunit.IRenderedFragment,Func{System.Boolean},System.Nullable{TimeSpan})) method covered on the page. Let's start by taking a look at the ` WaitForAssertion` method in more detail. ## Waiting for assertion to pass using `WaitForAssertion` -The [`WaitForAssertion(Action, TimeSpan?)`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForAssertion(Bunit.IRenderedFragmentBase,System.Action,System.Nullable{System.TimeSpan})) method can be used to block and wait in a test method until the provided assert action does not throw an exception, or until the timeout is reached (the default timeout is one second). +The [`WaitForAssertion(Action, TimeSpan?)`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForAssertion(Bunit.IRenderedFragment,Action,System.Nullable{TimeSpan})) method can be used to block and wait in a test method until the provided assert action does not throw an exception, or until the timeout is reached (the default timeout is one second). > [!NOTE] > The `WaitForAssertion()` method will try the assert action passed to it when the `WaitForAssertion()` method is called and every time the component under test renders. diff --git a/docs/site/docs/verification/verify-component-state.md b/docs/site/docs/verification/verify-component-state.md index e2f4f6c13..8eb9a2c9d 100644 --- a/docs/site/docs/verification/verify-component-state.md +++ b/docs/site/docs/verification/verify-component-state.md @@ -5,7 +5,7 @@ title: Verifying the state of a component under test # Verifying the state of a component -The instance of a component under test is available through the property on the type. When using the 's `RenderComponent()` method, this is the type returned. +The instance of a component under test is available through the property on the type. When using the 's `RenderComponent()` method, this is the type returned. In `.razor` based tests, using the 's method also returns an (as opposed to the method which returns the more simple ). @@ -14,7 +14,7 @@ In `.razor` based tests, using the 's property on the type provides access to the component under test. For example: +The property on the type provides access to the component under test. For example: ```csharp IRenderedComponent cut = RenderComponent(); @@ -25,9 +25,9 @@ Alert alert = cut.Instance; ``` > [!WARNING] -> While it is possible to set `[Parameter]` and `[CascadingParameter]` properties directly through the property on the type, doing so does not implicitly trigger a render and the component life-cycle methods are not called. +> While it is possible to set `[Parameter]` and `[CascadingParameter]` properties directly through the property on the type, doing so does not implicitly trigger a render and the component life-cycle methods are not called. > -> The correct approach is to set parameters through the [`SetParametersAndRender()`](xref:Bunit.RenderedComponentRenderExtensions.SetParametersAndRender``1(Bunit.IRenderedComponentBase{``0},System.Action{Bunit.ComponentParameterCollectionBuilder{``0}})) methods. See the page for more on this. +> The correct approach is to set parameters through the [`SetParametersAndRender()`](xref:Bunit.RenderedComponentRenderExtensions.SetParametersAndRender``1(Bunit.IRenderedComponent{``0},Action{Bunit.ComponentParameterCollectionBuilder{``0}})) methods. See the page for more on this. ## Finding Components in the Render Tree diff --git a/src/bunit/Asserting/CompareToExtensions.cs b/src/bunit/Asserting/CompareToExtensions.cs index bb30c2137..5da74b14b 100644 --- a/src/bunit/Asserting/CompareToExtensions.cs +++ b/src/bunit/Asserting/CompareToExtensions.cs @@ -10,7 +10,7 @@ namespace Bunit; public static class CompareToExtensions { /// - /// Compare the rendered markup in the + /// Compare the rendered markup in the /// with that in the markup string. /// /// Source of rendered markup to check. @@ -28,8 +28,8 @@ public static IReadOnlyList CompareTo(this IRenderedFragment actual, stri } /// - /// Compare the rendered markup in the to - /// the rendered markup in the . + /// Compare the rendered markup in the to + /// the rendered markup in the . /// /// Source of rendered markup to check. /// Source of rendered markup to compare with. diff --git a/src/bunit/Asserting/MarkupMatchesAssertExtensions.cs b/src/bunit/Asserting/MarkupMatchesAssertExtensions.cs index 8cb96e004..2228e5759 100644 --- a/src/bunit/Asserting/MarkupMatchesAssertExtensions.cs +++ b/src/bunit/Asserting/MarkupMatchesAssertExtensions.cs @@ -278,7 +278,7 @@ public static void MarkupMatches(this IRenderedFragment actual, RenderFragment e actual.Services.GetRequiredService(), actual.Services.GetRequiredService(), actual.Services.GetRequiredService()); - var renderedFragment = (IRenderedFragment)renderer.RenderFragment(expected); + var renderedFragment = renderer.RenderFragment(expected); MarkupMatches(actual, renderedFragment, userMessage); } @@ -414,7 +414,7 @@ public static void MarkupMatches(this IEnumerable actual, IEnumerable< private static IRenderedFragment AdhocRenderRenderFragment(this RenderFragment renderFragment) { using var ctx = new TestContext(); - return (IRenderedFragment)ctx.RenderInsideRenderTree(renderFragment); + return ctx.RenderInsideRenderTree(renderFragment); } private static INodeList ToNodeList(this string markup, BunitHtmlParser? htmlParser) diff --git a/src/bunit/ComponentFactories/GenericComponentFactory{TComponent,TSubstituteComponent}.cs b/src/bunit/ComponentFactories/GenericComponentFactory{TComponent,TSubstituteComponent}.cs index 17dc53538..1a433fa6e 100644 --- a/src/bunit/ComponentFactories/GenericComponentFactory{TComponent,TSubstituteComponent}.cs +++ b/src/bunit/ComponentFactories/GenericComponentFactory{TComponent,TSubstituteComponent}.cs @@ -2,9 +2,9 @@ namespace Bunit.ComponentFactories; internal sealed class GenericComponentFactory : IComponentFactory where TComponent : IComponent - where TSubstituteComponent : IComponent + where TSubstituteComponent : IComponent, new() { public bool CanCreate(Type componentType) => componentType == typeof(TComponent); - public IComponent Create(Type componentType) => Activator.CreateInstance()!; + public IComponent Create(Type componentType) => new TSubstituteComponent(); } diff --git a/src/bunit/Extensions/ComponentFactoryCollectionExtensions.cs b/src/bunit/Extensions/ComponentFactoryCollectionExtensions.cs index d17d27788..9bcf467e3 100644 --- a/src/bunit/Extensions/ComponentFactoryCollectionExtensions.cs +++ b/src/bunit/Extensions/ComponentFactoryCollectionExtensions.cs @@ -18,7 +18,7 @@ public static class ComponentFactoryCollectionExtensions /// A . public static ComponentFactoryCollection Add(this ComponentFactoryCollection factories) where TComponent : IComponent - where TSubstituteComponent : IComponent + where TSubstituteComponent : IComponent, new() { ArgumentNullException.ThrowIfNull(factories); diff --git a/src/bunit/Extensions/IRefreshableElementCollection.cs b/src/bunit/Extensions/IRefreshableElementCollection.cs index 285d0ee5b..5cc71a27e 100644 --- a/src/bunit/Extensions/IRefreshableElementCollection.cs +++ b/src/bunit/Extensions/IRefreshableElementCollection.cs @@ -4,7 +4,7 @@ namespace Bunit; /// /// Represents a collection, which queries and finds its -/// elements in an , based on a CSS selector. +/// elements in an , based on a CSS selector. /// The collection can be refreshed either manually or automatically. /// /// The type of in the collection. @@ -13,7 +13,7 @@ public interface IRefreshableElementCollection : IReadOnlyList { /// /// Gets or sets a value indicating whether the collection automatically refreshes when the - /// changes. + /// changes. /// bool EnableAutoRefresh { get; set; } diff --git a/src/bunit/Extensions/RenderedComponentRenderExtensions.cs b/src/bunit/Extensions/RenderedComponentRenderExtensions.cs index a6de0a34b..a210d137f 100644 --- a/src/bunit/Extensions/RenderedComponentRenderExtensions.cs +++ b/src/bunit/Extensions/RenderedComponentRenderExtensions.cs @@ -4,7 +4,7 @@ namespace Bunit; /// -/// Re-render extension methods, optionally with new parameters, for . +/// Re-render extension methods, optionally with new parameters, for . /// public static class RenderedComponentRenderExtensions { @@ -13,7 +13,7 @@ public static class RenderedComponentRenderExtensions /// /// The rendered component to re-render. /// The type of the component. - public static void Render(this IRenderedComponentBase renderedComponent) + public static void Render(this IRenderedComponent renderedComponent) where TComponent : IComponent => SetParametersAndRender(renderedComponent, ParameterView.Empty); @@ -23,7 +23,7 @@ public static void Render(this IRenderedComponentBase re /// The rendered component to re-render with new parameters. /// Parameters to pass to the component upon rendered. /// The type of the component. - public static void SetParametersAndRender(this IRenderedComponentBase renderedComponent, ParameterView parameters) + public static void SetParametersAndRender(this IRenderedComponent renderedComponent, ParameterView parameters) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(renderedComponent); @@ -46,7 +46,7 @@ public static void SetParametersAndRender(this IRenderedComponentBas /// The rendered component to re-render with new parameters. /// Parameters to pass to the component upon rendered. /// The type of the component. - public static void SetParametersAndRender(this IRenderedComponentBase renderedComponent, params ComponentParameter[] parameters) + public static void SetParametersAndRender(this IRenderedComponent renderedComponent, params ComponentParameter[] parameters) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(renderedComponent); @@ -61,7 +61,7 @@ public static void SetParametersAndRender(this IRenderedComponentBas /// The rendered component to re-render with new parameters. /// An action that receives a . /// The type of the component. - public static void SetParametersAndRender(this IRenderedComponentBase renderedComponent, Action> parameterBuilder) + public static void SetParametersAndRender(this IRenderedComponent renderedComponent, Action> parameterBuilder) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(renderedComponent); diff --git a/src/bunit/Extensions/RenderedFragmentExtensions.cs b/src/bunit/Extensions/RenderedFragmentExtensions.cs index af888b3f2..236b90bb2 100644 --- a/src/bunit/Extensions/RenderedFragmentExtensions.cs +++ b/src/bunit/Extensions/RenderedFragmentExtensions.cs @@ -56,7 +56,7 @@ public static IRenderedComponent FindComponent(this IRen ArgumentNullException.ThrowIfNull(renderedFragment); var renderer = renderedFragment.Services.GetRequiredService().Renderer; - return (IRenderedComponent)renderer.FindComponent(renderedFragment); + return renderer.FindComponent(renderedFragment); } /// diff --git a/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs b/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs index 6f0b6e04c..c95505202 100644 --- a/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs +++ b/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs @@ -3,7 +3,7 @@ namespace Bunit; /// -/// InvokeAsync extensions methods on . +/// InvokeAsync extensions methods on . /// public static class RenderedFragmentInvokeAsyncExtensions { @@ -13,7 +13,7 @@ public static class RenderedFragmentInvokeAsyncExtensions /// The rendered fragment whose dispatcher to invoke with. /// The work item to execute on the renderer's thread. /// A that will be completed when the action has finished executing or is suspended by an asynchronous operation. - public static Task InvokeAsync(this IRenderedFragmentBase renderedFragment, Action workItem) + public static Task InvokeAsync(this IRenderedFragment renderedFragment, Action workItem) { ArgumentNullException.ThrowIfNull(renderedFragment); @@ -31,7 +31,7 @@ public static Task InvokeAsync(this IRenderedFragmentBase renderedFragment, Acti /// The rendered component whose dispatcher to invoke with. /// The work item to execute on the renderer's thread. /// A that will be completed when the action has finished executing. - public static Task InvokeAsync(this IRenderedFragmentBase renderedFragment, Func workItem) + public static Task InvokeAsync(this IRenderedFragment renderedFragment, Func workItem) { ArgumentNullException.ThrowIfNull(renderedFragment); @@ -49,7 +49,7 @@ public static Task InvokeAsync(this IRenderedFragmentBase renderedFragment, Func /// The rendered component whose dispatcher to invoke with. /// The work item to execute on the renderer's thread. /// A that will be completed when the action has finished executing, with the return value from . - public static Task InvokeAsync(this IRenderedFragmentBase renderedFragment, Func workItem) + public static Task InvokeAsync(this IRenderedFragment renderedFragment, Func workItem) { ArgumentNullException.ThrowIfNull(renderedFragment); @@ -67,7 +67,7 @@ public static Task InvokeAsync(this IRenderedFragmentBase renderedFragment /// The rendered component whose dispatcher to invoke with. /// The work item to execute on the renderer's thread. /// A that will be completed when the action has finished executing, with the return value from . - public static Task InvokeAsync(this IRenderedFragmentBase renderedFragment, Func> workItem) + public static Task InvokeAsync(this IRenderedFragment renderedFragment, Func> workItem) { ArgumentNullException.ThrowIfNull(renderedFragment); diff --git a/src/bunit/Extensions/TestContextBaseRenderExtensions.cs b/src/bunit/Extensions/TestContextBaseRenderExtensions.cs index 53c6abd49..88126a3c2 100644 --- a/src/bunit/Extensions/TestContextBaseRenderExtensions.cs +++ b/src/bunit/Extensions/TestContextBaseRenderExtensions.cs @@ -13,8 +13,8 @@ public static class TestContextBaseRenderExtensions /// The type of component to render. /// Test context to use to render with. /// The that contains a declaration of the component. - /// A . - public static IRenderedComponentBase RenderInsideRenderTree(this TestContextBase testContext, RenderFragment renderFragment) + /// A . + public static IRenderedComponent RenderInsideRenderTree(this TestContextBase testContext, RenderFragment renderFragment) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(testContext); @@ -28,8 +28,8 @@ public static IRenderedComponentBase RenderInsideRenderTree /// Test context to use to render with. /// The to render. - /// A . - public static IRenderedFragmentBase RenderInsideRenderTree(this TestContextBase testContext, RenderFragment renderFragment) + /// A . + public static IRenderedFragment RenderInsideRenderTree(this TestContextBase testContext, RenderFragment renderFragment) { ArgumentNullException.ThrowIfNull(testContext); diff --git a/src/bunit/Extensions/TestServiceProviderExtensions.cs b/src/bunit/Extensions/TestServiceProviderExtensions.cs index c93faa0ec..40fca7ba0 100644 --- a/src/bunit/Extensions/TestServiceProviderExtensions.cs +++ b/src/bunit/Extensions/TestServiceProviderExtensions.cs @@ -31,7 +31,7 @@ public static IServiceCollection AddDefaultTestContextServices(this IServiceColl services.AddSingleton(); // bUnits fake JSInterop - services.AddSingleton(jsInterop.JSRuntime); + services.AddSingleton(jsInterop.JSRuntime); // bUnits fake Navigation Manager services.AddSingleton(); diff --git a/src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForState.cs b/src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForState.cs index a270ebbbf..f2eb51d49 100644 --- a/src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForState.cs +++ b/src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForState.cs @@ -23,7 +23,7 @@ public static partial class RenderedFragmentWaitForHelperExtensions /// /// If a debugger is attached the timeout is set to , giving the possibility to debug without the timeout triggering. /// - public static void WaitForState(this IRenderedFragmentBase renderedFragment, Func statePredicate, TimeSpan? timeout = null) + public static void WaitForState(this IRenderedFragment renderedFragment, Func statePredicate, TimeSpan? timeout = null) { using var waiter = new WaitForStateHelper(renderedFragment, statePredicate, timeout); @@ -48,7 +48,7 @@ public static void WaitForState(this IRenderedFragmentBase renderedFragment, Fun /// The predicate to invoke after each render, which must returns true when the desired state has been reached. /// The maximum time to wait for the desired state. /// Thrown if the throw an exception during invocation, or if the timeout has been reached. See the inner exception for details. - internal static async Task WaitForStateAsync(this IRenderedFragmentBase renderedFragment, Func statePredicate, TimeSpan? timeout = null) + internal static async Task WaitForStateAsync(this IRenderedFragment renderedFragment, Func statePredicate, TimeSpan? timeout = null) { using var waiter = new WaitForStateHelper(renderedFragment, statePredicate, timeout); @@ -66,7 +66,7 @@ internal static async Task WaitForStateAsync(this IRenderedFragmentBase rendered /// The maximum time to attempt the verification. /// Thrown if the timeout has been reached. See the inner exception to see the captured assertion exception. [AssertionMethod] - public static void WaitForAssertion(this IRenderedFragmentBase renderedFragment, Action assertion, TimeSpan? timeout = null) + public static void WaitForAssertion(this IRenderedFragment renderedFragment, Action assertion, TimeSpan? timeout = null) { using var waiter = new WaitForAssertionHelper(renderedFragment, assertion, timeout); @@ -91,7 +91,7 @@ public static void WaitForAssertion(this IRenderedFragmentBase renderedFragment, /// The maximum time to attempt the verification. /// Thrown if the timeout has been reached. See the inner exception to see the captured assertion exception. [AssertionMethod] - internal static async Task WaitForAssertionAsync(this IRenderedFragmentBase renderedFragment, Action assertion, TimeSpan? timeout = null) + internal static async Task WaitForAssertionAsync(this IRenderedFragment renderedFragment, Action assertion, TimeSpan? timeout = null) { using var waiter = new WaitForAssertionHelper(renderedFragment, assertion, timeout); diff --git a/src/bunit/Extensions/WaitForHelpers/WaitForAssertionHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForAssertionHelper.cs index 95a9dcb80..a5e002a96 100644 --- a/src/bunit/Extensions/WaitForHelpers/WaitForAssertionHelper.cs +++ b/src/bunit/Extensions/WaitForHelpers/WaitForAssertionHelper.cs @@ -26,7 +26,7 @@ public class WaitForAssertionHelper : WaitForHelper /// /// If a debugger is attached the timeout is set to , giving the possibility to debug without the timeout triggering. /// - public WaitForAssertionHelper(IRenderedFragmentBase renderedFragment, Action assertion, TimeSpan? timeout = null) + public WaitForAssertionHelper(IRenderedFragment renderedFragment, Action assertion, TimeSpan? timeout = null) : base( renderedFragment, () => diff --git a/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs index 033c8c27a..6e26324a6 100644 --- a/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs +++ b/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs @@ -5,7 +5,7 @@ namespace Bunit.Extensions.WaitForHelpers; /// -/// Represents a helper class that can wait for a render notifications from a type, +/// Represents a helper class that can wait for a render notifications from a type, /// until a specific timeout is reached. /// public abstract class WaitForHelper : IDisposable @@ -13,7 +13,7 @@ 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; + private readonly IRenderedFragment renderedFragment; private readonly ILogger> logger; private readonly TestRenderer renderer; private bool isDisposed; @@ -46,7 +46,7 @@ public abstract class WaitForHelper : IDisposable /// Initializes a new instance of the class. /// protected WaitForHelper( - IRenderedFragmentBase renderedFragment, + IRenderedFragment renderedFragment, Func<(bool CheckPassed, T Content)> completeChecker, TimeSpan? timeout = null) { diff --git a/src/bunit/Extensions/WaitForHelpers/WaitForStateHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForStateHelper.cs index 0fe7f86a0..4ee219c02 100644 --- a/src/bunit/Extensions/WaitForHelpers/WaitForStateHelper.cs +++ b/src/bunit/Extensions/WaitForHelpers/WaitForStateHelper.cs @@ -29,7 +29,7 @@ public class WaitForStateHelper : WaitForHelper /// The predicate to invoke after each render, which must returns true when the desired state has been reached. /// The maximum time to wait for the desired state. /// Thrown if the throw an exception during invocation, or if the timeout has been reached. See the inner exception for details. - public WaitForStateHelper(IRenderedFragmentBase renderedFragment, Func statePredicate, TimeSpan? timeout = null) + public WaitForStateHelper(IRenderedFragment renderedFragment, Func statePredicate, TimeSpan? timeout = null) : base(renderedFragment, () => (statePredicate(), default), timeout) { } diff --git a/src/bunit/IRenderedComponent.cs b/src/bunit/IRenderedComponent.cs index 2326e23dc..175535f1c 100644 --- a/src/bunit/IRenderedComponent.cs +++ b/src/bunit/IRenderedComponent.cs @@ -1,7 +1,11 @@ namespace Bunit; /// -public interface IRenderedComponent : IRenderedComponentBase, IRenderedFragment +public interface IRenderedComponent : IRenderedFragment where TComponent : IComponent { + /// + /// Gets the component under test. + /// + TComponent Instance { get; } } diff --git a/src/bunit/IRenderedComponentBase.cs b/src/bunit/IRenderedComponentBase.cs deleted file mode 100644 index a09544827..000000000 --- a/src/bunit/IRenderedComponentBase.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Bunit; - -/// -/// Represents a rendered component-under-test. -/// -/// The type of the component under test. -public interface IRenderedComponentBase : IRenderedFragmentBase - where TComponent : IComponent -{ - /// - /// Gets the component under test. - /// - TComponent Instance { get; } -} diff --git a/src/bunit/IRenderedFragment.cs b/src/bunit/IRenderedFragment.cs index dcb6a0514..61a1a0192 100644 --- a/src/bunit/IRenderedFragment.cs +++ b/src/bunit/IRenderedFragment.cs @@ -1,15 +1,45 @@ -using AngleSharp.Diffing.Core; using AngleSharp.Dom; +using Bunit.Rendering; namespace Bunit; /// /// Represents a rendered fragment. /// -public interface IRenderedFragment : IRenderedFragmentBase +public interface IRenderedFragment : IDisposable { /// - /// An event that is raised after the markup of the is updated. + /// Gets the total number times the fragment has been through its render life-cycle. + /// + int RenderCount { get; } + + /// + /// Gets a value indicating whether the rendered component or fragment has been disposed by the . + /// + bool IsDisposed { get; } + + /// + /// Gets the id of the rendered component or fragment. + /// + int ComponentId { get; } + + /// + /// Called by the owning when it finishes a render. + /// + /// A that represents a render. + void OnRender(RenderEvent renderEvent); + + /// + /// Gets the used when rendering the component. + /// + IServiceProvider Services { get; } + + /// + /// Adds or removes an event handler that will be triggered after each render of this . + /// + event EventHandler OnAfterRender; + /// + /// An event that is raised after the markup of the is updated. /// event EventHandler OnMarkupUpdated; diff --git a/src/bunit/IRenderedFragmentBase.cs b/src/bunit/IRenderedFragmentBase.cs deleted file mode 100644 index 920bd73f9..000000000 --- a/src/bunit/IRenderedFragmentBase.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Bunit.Rendering; - -namespace Bunit; - -/// -/// Represents a rendered . -/// -public interface IRenderedFragmentBase : IDisposable -{ - /// - /// Gets the total number times the fragment has been through its render life-cycle. - /// - int RenderCount { get; } - - /// - /// Gets a value indicating whether the rendered component or fragment has been disposed by the . - /// - bool IsDisposed { get; } - - /// - /// Gets the id of the rendered component or fragment. - /// - int ComponentId { get; } - - /// - /// Called by the owning when it finishes a render. - /// - /// A that represents a render. - void OnRender(RenderEvent renderEvent); - - /// - /// Gets the used when rendering the component. - /// - IServiceProvider Services { get; } - - /// - /// Adds or removes an event handler that will be triggered after each render of this . - /// - event EventHandler OnAfterRender; -} diff --git a/src/bunit/Rendering/ComponentDisposedException.cs b/src/bunit/Rendering/ComponentDisposedException.cs index 9ffb6cbd9..634d311f1 100644 --- a/src/bunit/Rendering/ComponentDisposedException.cs +++ b/src/bunit/Rendering/ComponentDisposedException.cs @@ -1,7 +1,7 @@ namespace Bunit.Rendering; /// -/// Represents an exception that is thrown when a 's +/// Represents an exception that is thrown when a 's /// properties is accessed after the underlying component has been disposed by the renderer. /// [Serializable] diff --git a/src/bunit/Rendering/IRenderedComponentActivator.cs b/src/bunit/Rendering/IRenderedComponentActivator.cs index f5593575b..faf6b36dd 100644 --- a/src/bunit/Rendering/IRenderedComponentActivator.cs +++ b/src/bunit/Rendering/IRenderedComponentActivator.cs @@ -1,25 +1,25 @@ namespace Bunit.Rendering; /// -/// Represents an activator for and types. +/// Represents an activator for and types. /// public interface IRenderedComponentActivator { /// - /// Creates an with the specified . + /// Creates an with the specified . /// - IRenderedFragmentBase CreateRenderedFragment(int componentId); + IRenderedFragment CreateRenderedFragment(int componentId); /// - /// Creates an with the specified . + /// Creates an with the specified . /// - IRenderedComponentBase CreateRenderedComponent(int componentId) + IRenderedComponent CreateRenderedComponent(int componentId) where TComponent : IComponent; /// - /// Creates an with the specified , + /// Creates an with the specified , /// , and . /// - IRenderedComponentBase CreateRenderedComponent(int componentId, TComponent component, RenderTreeFrameDictionary componentFrames) + IRenderedComponent CreateRenderedComponent(int componentId, TComponent component, RenderTreeFrameDictionary componentFrames) where TComponent : IComponent; } diff --git a/src/bunit/Rendering/ITestRenderer.cs b/src/bunit/Rendering/ITestRenderer.cs index 50f8d3e72..5e445dec0 100644 --- a/src/bunit/Rendering/ITestRenderer.cs +++ b/src/bunit/Rendering/ITestRenderer.cs @@ -46,16 +46,16 @@ Task DispatchEventAsync( /// Renders the . ///
/// The to render. - /// A that provides access to the rendered . - IRenderedFragmentBase RenderFragment(RenderFragment renderFragment); + /// A that provides access to the rendered . + IRenderedFragment RenderFragment(RenderFragment renderFragment); /// /// Renders a with the passed to it. /// /// The type of component to render. /// The parameters to pass to the component. - /// A that provides access to the rendered component. - IRenderedComponentBase RenderComponent(ComponentParameterCollection parameters) + /// A that provides access to the rendered component. + IRenderedComponent RenderComponent(ComponentParameterCollection parameters) where TComponent : IComponent; /// @@ -63,7 +63,7 @@ IRenderedComponentBase RenderComponent(ComponentParamete /// /// Type of component to find. /// Parent component to search. - IRenderedComponentBase FindComponent(IRenderedFragmentBase parentComponent) + IRenderedComponent FindComponent(IRenderedFragment parentComponent) where TComponent : IComponent; /// @@ -71,7 +71,7 @@ IRenderedComponentBase FindComponent(IRenderedFragmentBa /// /// Type of components to find. /// Parent component to search. - IReadOnlyList> FindComponents(IRenderedFragmentBase parentComponent) + IReadOnlyList> FindComponents(IRenderedFragment parentComponent) where TComponent : IComponent; /// diff --git a/src/bunit/Rendering/RenderEvent.cs b/src/bunit/Rendering/RenderEvent.cs index bbb410653..cd8561e16 100644 --- a/src/bunit/Rendering/RenderEvent.cs +++ b/src/bunit/Rendering/RenderEvent.cs @@ -20,7 +20,7 @@ public sealed class RenderEvent /// /// The to get the status for. /// A tuple of statuses indicating whether the rendered component rendered during the render cycle, if it changed or if it was disposed. - public (bool Rendered, bool Changed, bool Disposed) GetRenderStatus(IRenderedFragmentBase renderedComponent) + public (bool Rendered, bool Changed, bool Disposed) GetRenderStatus(IRenderedFragment renderedComponent) { ArgumentNullException.ThrowIfNull(renderedComponent); diff --git a/src/bunit/Rendering/RenderedComponentActivator.cs b/src/bunit/Rendering/RenderedComponentActivator.cs index 23b2e944c..a557c2073 100644 --- a/src/bunit/Rendering/RenderedComponentActivator.cs +++ b/src/bunit/Rendering/RenderedComponentActivator.cs @@ -16,16 +16,16 @@ public RenderedComponentActivator(IServiceProvider services) } /// - public IRenderedFragmentBase CreateRenderedFragment(int componentId) + public IRenderedFragment CreateRenderedFragment(int componentId) => new RenderedFragment(componentId, services); /// - public IRenderedComponentBase CreateRenderedComponent(int componentId) + public IRenderedComponent CreateRenderedComponent(int componentId) where TComponent : IComponent => new RenderedComponent(componentId, services); /// - public IRenderedComponentBase CreateRenderedComponent(int componentId, TComponent component, RenderTreeFrameDictionary componentFrames) + public IRenderedComponent CreateRenderedComponent(int componentId, TComponent component, RenderTreeFrameDictionary componentFrames) where TComponent : IComponent => new RenderedComponent(componentId, component, componentFrames, services); } diff --git a/src/bunit/Rendering/RenderedFragment.cs b/src/bunit/Rendering/RenderedFragment.cs index e643e58d4..8b5e30785 100644 --- a/src/bunit/Rendering/RenderedFragment.cs +++ b/src/bunit/Rendering/RenderedFragment.cs @@ -78,7 +78,7 @@ internal RenderedFragment(int componentId, IServiceProvider service) htmlParser = Services.GetRequiredService(); } - void IRenderedFragmentBase.OnRender(RenderEvent renderEvent) + void IRenderedFragment.OnRender(RenderEvent renderEvent) { if (IsDisposed) return; diff --git a/src/bunit/Rendering/TestRenderer.cs b/src/bunit/Rendering/TestRenderer.cs index f78298ffc..06e787d62 100644 --- a/src/bunit/Rendering/TestRenderer.cs +++ b/src/bunit/Rendering/TestRenderer.cs @@ -17,7 +17,7 @@ public class TestRenderer : Renderer, ITestRenderer extern static void CallSetDirectParameters(ComponentState componentState, ParameterView parameters); private readonly object renderTreeUpdateLock = new(); - private readonly Dictionary renderedComponents = new(); + private readonly Dictionary renderedComponents = new(); private readonly List rootComponents = new(); private readonly ILogger logger; private readonly IRenderedComponentActivator activator; @@ -57,7 +57,8 @@ public TestRenderer(IRenderedComponentActivator renderedComponentActivator, Test : base(services, loggerFactory, new BunitComponentActivator(services.GetRequiredService(), null)) { logger = loggerFactory.CreateLogger(); - this.activator = renderedComponentActivator; + activator = renderedComponentActivator; + ElementReferenceContext = new WebElementReferenceContext(services.GetRequiredService()); } /// @@ -67,15 +68,16 @@ public TestRenderer(IRenderedComponentActivator renderedComponentActivator, Test : base(services, loggerFactory, new BunitComponentActivator(services.GetRequiredService(), componentActivator)) { logger = loggerFactory.CreateLogger(); - this.activator = renderedComponentActivator; + activator = renderedComponentActivator; + ElementReferenceContext = new WebElementReferenceContext(services.GetRequiredService()); } /// - public IRenderedFragmentBase RenderFragment(RenderFragment renderFragment) + public IRenderedFragment RenderFragment(RenderFragment renderFragment) => Render(renderFragment, id => activator.CreateRenderedFragment(id)); /// - public IRenderedComponentBase RenderComponent(ComponentParameterCollection parameters) + public IRenderedComponent RenderComponent(ComponentParameterCollection parameters) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(parameters); @@ -141,7 +143,7 @@ public IRenderedComponentBase RenderComponent(ComponentP } /// - public IRenderedComponentBase FindComponent(IRenderedFragmentBase parentComponent) + public IRenderedComponent FindComponent(IRenderedFragment parentComponent) where TComponent : IComponent { var foundComponents = FindComponents(parentComponent, 1); @@ -151,7 +153,7 @@ public IRenderedComponentBase FindComponent(IRenderedFra } /// - public IReadOnlyList> FindComponents(IRenderedFragmentBase parentComponent) + public IReadOnlyList> FindComponents(IRenderedFragment parentComponent) where TComponent : IComponent => FindComponents(parentComponent, int.MaxValue); @@ -191,7 +193,7 @@ protected override IComponent ResolveComponentForRenderMode(Type componentType, } /// - internal Task SetDirectParametersAsync(IRenderedFragmentBase renderedComponent, ParameterView parameters) + internal Task SetDirectParametersAsync(IRenderedFragment renderedComponent, ParameterView parameters) { ObjectDisposedException.ThrowIf(disposed, this); @@ -399,7 +401,7 @@ protected override void Dispose(bool disposing) } private TResult Render(RenderFragment renderFragment, Func activator) - where TResult : IRenderedFragmentBase + where TResult : IRenderedFragment { ObjectDisposedException.ThrowIf(disposed, this); @@ -435,14 +437,14 @@ private TResult Render(RenderFragment renderFragment, Func> FindComponents(IRenderedFragmentBase parentComponent, int resultLimit) + private List> FindComponents(IRenderedFragment parentComponent, int resultLimit) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(parentComponent); ObjectDisposedException.ThrowIf(disposed, this); - var result = new List>(); + var result = new List>(); var framesCollection = new RenderTreeFrameDictionary(); // Blocks the renderer from changing the render tree @@ -482,12 +484,12 @@ void FindComponentsInRenderTree(int componentId) } } - private IRenderedComponentBase GetOrCreateRenderedComponent(RenderTreeFrameDictionary framesCollection, int componentId, TComponent component) + private IRenderedComponent GetOrCreateRenderedComponent(RenderTreeFrameDictionary framesCollection, int componentId, TComponent component) where TComponent : IComponent { if (renderedComponents.TryGetValue(componentId, out var renderedComponent)) { - return (IRenderedComponentBase)renderedComponent; + return (IRenderedComponent)renderedComponent; } LoadRenderTreeFrames(componentId, framesCollection); diff --git a/src/bunit/Rendering/WebTestRenderer.cs b/src/bunit/Rendering/WebTestRenderer.cs deleted file mode 100644 index 3a9a87a4b..000000000 --- a/src/bunit/Rendering/WebTestRenderer.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Microsoft.Extensions.Logging; - -namespace Bunit.Rendering; - -/// -/// Represents a that is used when rendering -/// Blazor components for the web. -/// -public class WebTestRenderer : TestRenderer -{ - /// - /// Initializes a new instance of the class. - /// - public WebTestRenderer(IRenderedComponentActivator renderedComponentActivator, TestServiceProvider services, ILoggerFactory loggerFactory) - : base(renderedComponentActivator, services, loggerFactory) - { - ElementReferenceContext = new WebElementReferenceContext(services.GetRequiredService()); - } - - /// - /// Initializes a new instance of the class. - /// - public WebTestRenderer(IRenderedComponentActivator renderedComponentActivator, TestServiceProvider services, ILoggerFactory loggerFactory, IComponentActivator componentActivator) - : base(renderedComponentActivator, services, loggerFactory, componentActivator) - { - ElementReferenceContext = new WebElementReferenceContext(services.GetRequiredService()); - } -} diff --git a/src/bunit/TestContext.cs b/src/bunit/TestContext.cs index a0ada8011..afcb45ff9 100644 --- a/src/bunit/TestContext.cs +++ b/src/bunit/TestContext.cs @@ -65,7 +65,7 @@ public virtual IRenderedComponent RenderComponent(Action /// The . public virtual IRenderedComponent Render(RenderFragment renderFragment) where TComponent : IComponent - => (IRenderedComponent)this.RenderInsideRenderTree(renderFragment); + => this.RenderInsideRenderTree(renderFragment); /// /// Renders the and returns it as a . @@ -73,7 +73,7 @@ public virtual IRenderedComponent Render(RenderFragment /// The render fragment to render. /// The . public virtual IRenderedFragment Render(RenderFragment renderFragment) - => (IRenderedFragment)this.RenderInsideRenderTree(renderFragment); + => this.RenderInsideRenderTree(renderFragment); /// /// Dummy method required to allow Blazor's compiler to generate @@ -89,7 +89,7 @@ protected override ITestRenderer CreateTestRenderer() var componentActivator = Services.GetService(); return componentActivator is null - ? new WebTestRenderer(renderedComponentActivator, Services, logger) - : new WebTestRenderer(renderedComponentActivator, Services, logger, componentActivator); + ? new TestRenderer(renderedComponentActivator, Services, logger) + : new TestRenderer(renderedComponentActivator, Services, logger, componentActivator); } } diff --git a/src/bunit/TestContextBase.cs b/src/bunit/TestContextBase.cs index cd660e5f8..95e999590 100644 --- a/src/bunit/TestContextBase.cs +++ b/src/bunit/TestContextBase.cs @@ -11,7 +11,7 @@ public abstract class TestContextBase : IDisposable private ITestRenderer? testRenderer; /// - /// Gets or sets the default wait timeout used by "WaitFor" operations, i.e. . + /// Gets or sets the default wait timeout used by "WaitFor" operations, i.e. . /// /// The default is 1 second. public static TimeSpan DefaultWaitTimeout { get; set; } = TimeSpan.FromSeconds(1); diff --git a/tests/bunit.tests/ComponentParameterCollectionBuilderTests.cs b/tests/bunit.tests/ComponentParameterCollectionBuilderTests.cs index fcce39230..77a60513d 100644 --- a/tests/bunit.tests/ComponentParameterCollectionBuilderTests.cs +++ b/tests/bunit.tests/ComponentParameterCollectionBuilderTests.cs @@ -39,13 +39,13 @@ private async Task VerifyEventCallbackAsync(string expectedName) private IRenderedFragment RenderWithRenderFragment(RenderFragment renderFragment) { - return (IRenderedFragment)Renderer.RenderFragment(renderFragment); + return Renderer.RenderFragment(renderFragment); } private IRenderedComponent RenderWithRenderFragment(RenderFragment renderFragment) where TComponent : IComponent { - var res = (IRenderedFragment)Renderer.RenderFragment(renderFragment); + var res = Renderer.RenderFragment(renderFragment); return res.FindComponent(); } diff --git a/tests/bunit.tests/ComponentParameterCollectionTest.cs b/tests/bunit.tests/ComponentParameterCollectionTest.cs index 6a809a206..99b0250b6 100644 --- a/tests/bunit.tests/ComponentParameterCollectionTest.cs +++ b/tests/bunit.tests/ComponentParameterCollectionTest.cs @@ -4,7 +4,7 @@ public class ComponentParameterCollectionTest : TestContext { private IRenderedComponent RenderWithRenderFragment(RenderFragment renderFragment) { - var res = (IRenderedFragment)Renderer.RenderFragment(renderFragment); + var res = Renderer.RenderFragment(renderFragment); return res.FindComponent(); } diff --git a/tests/bunit.tests/ComponentParameterFactoryTest.cs b/tests/bunit.tests/ComponentParameterFactoryTest.cs index e642e2317..d3dc660d5 100644 --- a/tests/bunit.tests/ComponentParameterFactoryTest.cs +++ b/tests/bunit.tests/ComponentParameterFactoryTest.cs @@ -10,7 +10,7 @@ public class ComponentParameterFactoryTest private static IRenderedFragment RenderWithRenderFragment(RenderFragment renderFragment) { - return (IRenderedFragment)Context.Renderer.RenderFragment(renderFragment); + return Context.Renderer.RenderFragment(renderFragment); } private string? Actual { get; set; } diff --git a/tests/bunit.tests/Rendering/TestRendererTest.cs b/tests/bunit.tests/Rendering/TestRendererTest.cs index d7347b509..a4e1ecf2f 100644 --- a/tests/bunit.tests/Rendering/TestRendererTest.cs +++ b/tests/bunit.tests/Rendering/TestRendererTest.cs @@ -38,7 +38,7 @@ public void Test001() const string MARKUP = "

hello world

"; using var sut = CreateRenderer(); - var cut = (IRenderedFragment)sut.RenderFragment(builder => builder.AddMarkupContent(0, MARKUP)); + var cut = sut.RenderFragment(builder => builder.AddMarkupContent(0, MARKUP)); cut.RenderCount.ShouldBe(1); cut.Markup.ShouldBe(MARKUP); @@ -129,7 +129,7 @@ public void Test020() ChildContent((nameof(HasParams.Value), CHILD_VALUE))); // act - var childCut = (IRenderedComponent)sut.FindComponent(cut); + var childCut = sut.FindComponent(cut); // assert childCut.Markup.ShouldBe(CHILD_VALUE); @@ -231,7 +231,7 @@ public async Task Test040() ChildContent()); // act - var cut = (IRenderedComponent)sut.FindComponent(parent); + var cut = sut.FindComponent(parent); cut.RenderCount.ShouldBe(1); @@ -250,7 +250,7 @@ public async Task Test041() ChildContent()); // act - var cut = (IRenderedComponent)sut.FindComponents(parent).Single(); + var cut = sut.FindComponents(parent).Single(); cut.RenderCount.ShouldBe(1); @@ -268,7 +268,7 @@ public async Task Test050() var cut = sut.RenderComponent( ChildContent()); - var child = (IRenderedComponent)sut.FindComponent(cut); + var child = sut.FindComponent(cut); // act await child.Instance.TriggerWithValue("X"); @@ -286,7 +286,7 @@ public async Task Test060() var cut = sut.RenderComponent( ChildContent()); - var child = (IRenderedComponent)sut.FindComponent(cut); + var child = sut.FindComponent(cut); // act await cut.Instance.DisposeChild(); @@ -305,8 +305,8 @@ public async Task Test061() var cut = sut.RenderComponent( ChildContent( ChildContent())); - var child = (IRenderedComponent)sut.FindComponent(cut); - var childChild = (IRenderedComponent)sut.FindComponent(cut); + var child = sut.FindComponent(cut); + var childChild = sut.FindComponent(cut); // act await child.Instance.DisposeChild(); @@ -319,7 +319,7 @@ public async Task Test061() [Fact(DisplayName = "When test renderer is disposed, so is all rendered components")] public void Test070() { - var sut = (TestRenderer)CreateRenderer(); + var sut = CreateRenderer(); var cut = sut.RenderComponent(); sut.Dispose(); @@ -514,7 +514,7 @@ public void Test211() cut.Find("h1").TextContent.ShouldBe($"Hello world {RenderMode.InteractiveWebAssembly}"); } - private WebTestRenderer CreateRenderer() => new WebTestRenderer( + private TestRenderer CreateRenderer() => new TestRenderer( Services.GetRequiredService(), Services, NullLoggerFactory.Instance); From f6044475a85747d034adf058ed5651c48ce51b73 Mon Sep 17 00:00:00 2001 From: Steven Giesel Date: Sun, 3 Mar 2024 10:51:50 +0100 Subject: [PATCH 08/42] refactor: Rename Fake to Bunit --- MIGRATION.md | 6 ++ .../tests/xunit/InjectAuthServiceTest.cs | 4 +- docs/samples/tests/xunit/UserInfoTest.cs | 8 +- docs/samples/tests/xunit/UserRightsTest.cs | 16 ++-- .../passing-parameters-to-components.md | 2 +- .../test-doubles/{faking-auth.md => auth.md} | 20 ++--- .../fake-webassemblyhostenvironment.md | 16 ++-- docs/site/docs/test-doubles/index.md | 8 +- ...ation-manager.md => navigation-manager.md} | 20 ++--- ...ntstate.md => persistentcomponentstate.md} | 42 +++++----- docs/site/docs/toc.md | 8 +- .../TestServiceProviderExtensions.cs | 18 ++--- ...cs => BunitAuthenticationStateProvider.cs} | 14 ++-- ...ons.cs => BunitAuthorizationExtensions.cs} | 8 +- ...cs => BunitAuthorizationPolicyProvider.cs} | 2 +- ...ervice.cs => BunitAuthorizationService.cs} | 6 +- ... => MissingBunitAuthorizationException.cs} | 12 +-- .../PlaceholderAuthenticationStateProvider.cs | 2 +- .../PlaceholderAuthorizationService.cs | 4 +- .../Authorization/TestAuthorizationContext.cs | 6 +- ...tion.cs => BunitNavigationInterception.cs} | 2 +- ...onManager.cs => BunitNavigationManager.cs} | 13 ++-- ....cs => BunitSignOutSessionStateManager.cs} | 8 +- ...te.cs => BunitPersistentComponentState.cs} | 18 ++--- ... => BunitPersistentComponentStateStore.cs} | 2 +- .../TestContextBaseExtensions.cs | 12 +-- ....cs => BunitWebAssemblyHostEnvironment.cs} | 5 +- .../Authorization/AuthorizationTest.cs | 40 +++++----- ...> BunitAuthenticationStateProviderTest.cs} | 8 +- ...> BunitAuthorizationPolicyProviderTest.cs} | 12 +-- ...st.cs => BunitAuthorizationServiceTest.cs} | 14 ++-- .../TestAuthorizationContextTest.cs | 12 +-- ...=> BunitSignOutSessionStateManagerTest.cs} | 8 +- ...=> BunitWebAssemblyHostEnvironmentTest.cs} | 6 +- ....cs => BunitNavigationInterceptionTest.cs} | 6 +- ...rTest.cs => BunitNavigationManagerTest.cs} | 78 +++++++++---------- ...s => BunitPersistentComponentStateTest.cs} | 30 +++---- 37 files changed, 250 insertions(+), 246 deletions(-) rename docs/site/docs/test-doubles/{faking-auth.md => auth.md} (71%) rename docs/site/docs/test-doubles/{fake-navigation-manager.md => navigation-manager.md} (84%) rename docs/site/docs/test-doubles/{faking-persistentcomponentstate.md => persistentcomponentstate.md} (61%) rename src/bunit/TestDoubles/Authorization/{FakeAuthenticationStateProvider.cs => BunitAuthenticationStateProvider.cs} (90%) rename src/bunit/TestDoubles/Authorization/{FakeAuthorizationExtensions.cs => BunitAuthorizationExtensions.cs} (79%) rename src/bunit/TestDoubles/Authorization/{FakeAuthorizationPolicyProvider.cs => BunitAuthorizationPolicyProvider.cs} (95%) rename src/bunit/TestDoubles/Authorization/{FakeAuthorizationService.cs => BunitAuthorizationService.cs} (94%) rename src/bunit/TestDoubles/Authorization/{MissingFakeAuthorizationException.cs => MissingBunitAuthorizationException.cs} (62%) rename src/bunit/TestDoubles/NavigationInterception/{FakeNavigationInterception.cs => BunitNavigationInterception.cs} (66%) rename src/bunit/TestDoubles/NavigationManager/{FakeNavigationManager.cs => BunitNavigationManager.cs} (86%) rename src/bunit/TestDoubles/NavigationManager/{FakeSignOutSessionStateManager.cs => BunitSignOutSessionStateManager.cs} (67%) rename src/bunit/TestDoubles/PersistentComponentState/{FakePersistentComponentState.cs => BunitPersistentComponentState.cs} (87%) rename src/bunit/TestDoubles/PersistentComponentState/{FakePersistentComponentStateStore.cs => BunitPersistentComponentStateStore.cs} (85%) rename src/bunit/TestDoubles/WebAssemblyHostEnvironment/{FakeWebAssemblyHostEnvironment.cs => BunitWebAssemblyHostEnvironment.cs} (81%) rename tests/bunit.tests/TestDoubles/Authorization/{FakeAuthenticationStateProviderTest.cs => BunitAuthenticationStateProviderTest.cs} (85%) rename tests/bunit.tests/TestDoubles/Authorization/{FakeAuthorizationPolicyProviderTest.cs => BunitAuthorizationPolicyProviderTest.cs} (85%) rename tests/bunit.tests/TestDoubles/Authorization/{FakeAuthorizationServiceTest.cs => BunitAuthorizationServiceTest.cs} (83%) rename tests/bunit.tests/TestDoubles/{FakeSignOutSessionStateManagerTest.cs => BunitSignOutSessionStateManagerTest.cs} (64%) rename tests/bunit.tests/TestDoubles/{FakeWebAssemblyHostEnvironmentTest.cs => BunitWebAssemblyHostEnvironmentTest.cs} (73%) rename tests/bunit.tests/TestDoubles/NavigationManager/{FakeNavigationInterceptionTest.cs => BunitNavigationInterceptionTest.cs} (77%) rename tests/bunit.tests/TestDoubles/NavigationManager/{FakeNavigationManagerTest.cs => BunitNavigationManagerTest.cs} (80%) rename tests/bunit.tests/TestDoubles/PersistentComponentState/{FakePersistentComponentStateTest.cs => BunitPersistentComponentStateTest.cs} (58%) diff --git a/MIGRATION.md b/MIGRATION.md index fa9dd9e0d..cbafd337b 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -33,3 +33,9 @@ The `bunit.core` and `bunit.web` packages have been merged into a single `bunit` ### `WebTestRender` merged into `TestRender` The `WebTestRender` class has been merged into the `TestRender` class. If you used `WebTestRender`, you should replace it with `TestRender`. + +## Renamed `Fake` to `Bunit` in many test doubles +The `Fake` prefix has been replaced with `Bunit` in many test doubles. For example, `FakeNavigationManager` is now `BunitNavigationManager`. If you reference any of these types explicitly, you need to update your code. + +### Renamed `AddTestAuthorization` to `AddAuthorization` +The `AddTestAuthorization` method on `TestContext` has been renamed to `AddAuthorization`. If you used `AddTestAuthorization`, you should replace it with `AddAuthorization`. diff --git a/docs/samples/tests/xunit/InjectAuthServiceTest.cs b/docs/samples/tests/xunit/InjectAuthServiceTest.cs index c7a4d72eb..aa3bebc87 100644 --- a/docs/samples/tests/xunit/InjectAuthServiceTest.cs +++ b/docs/samples/tests/xunit/InjectAuthServiceTest.cs @@ -10,7 +10,7 @@ public class InjectAuthServiceTest : TestContext public void Test001() { // arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TestUserName", AuthorizationState.Authorized); // act @@ -24,7 +24,7 @@ public void Test001() public void Test002() { // arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); // act var cut = RenderComponent(); diff --git a/docs/samples/tests/xunit/UserInfoTest.cs b/docs/samples/tests/xunit/UserInfoTest.cs index c3616cd86..080e7cef0 100644 --- a/docs/samples/tests/xunit/UserInfoTest.cs +++ b/docs/samples/tests/xunit/UserInfoTest.cs @@ -9,7 +9,7 @@ public class UserInfoTest : TestContext public void Test001() { // Arrange - this.AddTestAuthorization(); + this.AddAuthorization(); // Act var cut = RenderComponent(); @@ -23,7 +23,7 @@ public void Test001() public void Test004() { // Arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorizing(); // Act @@ -38,7 +38,7 @@ public void Test004() public void Test002() { // Arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TEST USER", AuthorizationState.Unauthorized); // Act @@ -53,7 +53,7 @@ public void Test002() public void Test003() { // Arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TEST USER"); // Act diff --git a/docs/samples/tests/xunit/UserRightsTest.cs b/docs/samples/tests/xunit/UserRightsTest.cs index 3e3f82a2c..41d290701 100644 --- a/docs/samples/tests/xunit/UserRightsTest.cs +++ b/docs/samples/tests/xunit/UserRightsTest.cs @@ -11,7 +11,7 @@ public class UserRightsTest : TestContext public void Test001() { // Arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TEST USER"); // Act @@ -26,7 +26,7 @@ public void Test001() public void Test002() { // Arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TEST USER"); authContext.SetRoles("superuser"); @@ -44,7 +44,7 @@ public void Test002() public void Test003() { // Arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TEST USER"); authContext.SetRoles("admin", "superuser"); @@ -63,7 +63,7 @@ public void Test003() public void Test004() { // Arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TEST USER"); authContext.SetPolicies("content-editor"); @@ -81,7 +81,7 @@ public void Test004() public void Test0041() { // Arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TEST USER"); authContext.SetPolicies("content-editor", "approver"); @@ -99,7 +99,7 @@ public void Test0041() public void Test006() { // Arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TEST USER"); authContext.SetClaims( new Claim(ClaimTypes.Email, "test@example.com"), @@ -121,7 +121,7 @@ public void Test006() public void Test005() { // Arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TEST USER"); authContext.SetRoles("admin", "superuser"); authContext.SetPolicies("content-editor"); @@ -144,7 +144,7 @@ public void Test005() public void Test007() { // Arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TEST USER"); authContext.SetAuthenticationType("custom-auth-type"); diff --git a/docs/site/docs/providing-input/passing-parameters-to-components.md b/docs/site/docs/providing-input/passing-parameters-to-components.md index 4db2fccf1..a0a5be316 100644 --- a/docs/site/docs/providing-input/passing-parameters-to-components.md +++ b/docs/site/docs/providing-input/passing-parameters-to-components.md @@ -469,7 +469,7 @@ When rendering a `RenderFragment` using the 's `Add` method, if a component parameter is only annotated with the `[SupplyParameterFromQuery]` attribute. Instead, pass a query string parameters by setting it using the . +In .NET 8 however, the `[Parameter]` attribute is no longer required, which means a value cannot be passed to the component during testing using the normal methods, e.g. the 's `Add` method, if a component parameter is only annotated with the `[SupplyParameterFromQuery]` attribute. Instead, pass a query string parameters by setting it using the . For example: diff --git a/docs/site/docs/test-doubles/faking-auth.md b/docs/site/docs/test-doubles/auth.md similarity index 71% rename from docs/site/docs/test-doubles/faking-auth.md rename to docs/site/docs/test-doubles/auth.md index dd0d1a584..8a94cb728 100644 --- a/docs/site/docs/test-doubles/faking-auth.md +++ b/docs/site/docs/test-doubles/auth.md @@ -1,9 +1,9 @@ --- -uid: faking-auth -title: Faking authentication and authorization +uid: bunit-auth +title: Adding authentication and authorization --- -# Faking authentication and authorization +# Adding authentication and authorization bUnit comes with test-specific implementations of Blazor's authentication and authorization types, making it easy to test components that use Blazor's ``, `` and `` components, as well as the `AuthenticationStateProvider` type. @@ -15,10 +15,10 @@ The test implementation of Blazor's authentication and authorization can be put - **Authenticated** and **authorized** - **Authenticated** and **authorized** with one or more **roles**, **claims**, and/or **policies** -bUnit's authentication and authorization implementation is easily available by calling [`AddTestAuthorization()`](xref:Bunit.TestDoubles.FakeAuthorizationExtensions.AddTestAuthorization(Bunit.TestContextBase)) on a test context. This adds the necessary services to the `Services` collection and the `CascadingAuthenticationState` component to the [root render tree](xref:root-render-tree). The method returns an instance of the type that allows you to control the authentication and authorization state for a test. +bUnit's authentication and authorization implementation is easily available by calling [`AddAuthorization()`](xref:Bunit.TestDoubles.BunitAuthorizationExtensions.AddAuthorization(Bunit.TestContextBase)) on a test context. This adds the necessary services to the `Services` collection and the `CascadingAuthenticationState` component to the [root render tree](xref:root-render-tree). The method returns an instance of the type that allows you to control the authentication and authorization state for a test. > [!NOTE] -> If your test class inherits directly from bUnit's then you need to call the [`AddTestAuthorization()`](xref:Bunit.TestDoubles.FakeAuthorizationExtensions.AddTestAuthorization(Bunit.TestContextBase)) method on `this`, since `AddTestAuthorization()` is an extension method, otherwise it wont be available. E.g.: `this.AddTestAuthorization()`. +> If your test class inherits directly from bUnit's then you need to call the [`AddAuthorization()`](xref:Bunit.TestDoubles.BunitAuthorizationExtensions.AddAuthorization(Bunit.TestContextBase)) method on `this`, since `AddAuthorization()` is an extension method, otherwise it wont be available. E.g.: `this.AddAuthorization()`. The following sections show how to set each of these states in a test. @@ -36,9 +36,9 @@ To set the state to unauthenticated and unauthorized, do the following: [!code-csharp[UserInfoTest.cs](../../../samples/tests/xunit/UserInfoTest.cs?start=11&end=19&highlight=2)] -The highlighted line shows how `AddTestAuthorization()` is used to add the test-specific implementation of Blazor's authentication and authorization types to the `Services` collection, which makes the authentication state available to other services as well as components used throughout the test that require it. +The highlighted line shows how `AddAuthorization()` is used to add the test-specific implementation of Blazor's authentication and authorization types to the `Services` collection, which makes the authentication state available to other services as well as components used throughout the test that require it. -After calling `AddTestAuthorization()`, the default authentication state is unauthenticated and unauthorized. +After calling `AddAuthorization()`, the default authentication state is unauthenticated and unauthorized. ### Authenticating and authorizing state @@ -46,7 +46,7 @@ To set the state to authenticating and authorizing, do the following: [!code-csharp[UserInfoTest.cs](../../../samples/tests/xunit/UserInfoTest.cs?start=25&end=34&highlight=3)] -After calling `AddTestAuthorization()`, the returned is used to set the authenticating and authorizing state through the method. +After calling `AddAuthorization()`, the returned is used to set the authenticating and authorizing state through the method. ### Authenticated and unauthorized state @@ -54,7 +54,7 @@ To set the state to authenticated and unauthorized, do the following: [!code-csharp[UserInfoTest.cs](../../../samples/tests/xunit/UserInfoTest.cs?start=40&end=49&highlight=3)] -After calling `AddTestAuthorization()`, the returned is used to set the authenticated and unauthorized state through the method. +After calling `AddAuthorization()`, the returned is used to set the authenticated and unauthorized state through the method. ### Authenticated and authorized state @@ -62,7 +62,7 @@ To set the state to authenticated and authorized, do the following: [!code-csharp[UserInfoTest.cs](../../../samples/tests/xunit/UserInfoTest.cs?start=55&end=64&highlight=3)] -After calling `AddTestAuthorization()`, the returned is used to set the authenticated and authorized state through the method. +After calling `AddAuthorization()`, the returned is used to set the authenticated and authorized state through the method. Note that the second parameter, `AuthorizationState`, is optional, and defaults to `AuthorizationState.Authorized` if not specified. diff --git a/docs/site/docs/test-doubles/fake-webassemblyhostenvironment.md b/docs/site/docs/test-doubles/fake-webassemblyhostenvironment.md index edd86fe72..9bb8d5a95 100644 --- a/docs/site/docs/test-doubles/fake-webassemblyhostenvironment.md +++ b/docs/site/docs/test-doubles/fake-webassemblyhostenvironment.md @@ -1,17 +1,17 @@ --- -uid: fake-webassemblyhostenvironment -title: Faking IWebAssemblyHostEnvironment +uid: bunit-webassemblyhostenvironment +title: Adding IWebAssemblyHostEnvironment --- -# Faking `IWebAssemblyHostEnvironment` +# Adding `IWebAssemblyHostEnvironment` -bUnit has a fake implementation of Blazor's `IWebAssemblyHostEnvironment` built-in, which is added by default to bUnit's `TestContext.Services` service provider. That means nothing special is needed to test components that depend on `IWebAssemblyHostEnvironment`, as it is already available by default. +bUnit has itws own implementation of Blazor's `IWebAssemblyHostEnvironment` built-in, which is added by default to bUnit's `TestContext.Services` service provider. That means nothing special is needed to test components that depend on `IWebAssemblyHostEnvironment`, as it is already available by default. -Out of the box, the fake implementation has its `Environment` property set to `production`, and its `BaseAddress` set to `/`. +Out of the box, the implementation has its `Environment` property set to `production`, and its `BaseAddress` set to `/`. ## Setting `Environment` and `BaseAddress` -Lets look at a few examples of how to set the two `IWebAssemblyHostEnvironment` properties `Environment` and `BaseAddress` via the built-in fake. +Lets look at a few examples of how to set the two `IWebAssemblyHostEnvironment` properties `Environment` and `BaseAddress` via the built-in object. In the examples, we'll use the following `` component: @@ -30,7 +30,7 @@ To verify that the `` component correctly says hello to the develope ```csharp // Arrange -var hostEnvironment = Services.GetRequiredService(); +var hostEnvironment = Services.GetRequiredService(); // Sets the environment to "Development". There are two other helper // methods available as well, SetEnvironmentToProduction() and @@ -48,7 +48,7 @@ To verify that the `` component correctly uses the current `BaseAddr ```csharp // Arrange -var hostEnvironment = Services.GetRequiredService(); +var hostEnvironment = Services.GetRequiredService(); // Sets a new base address directly on the BaseAddress property. hostEnvironment.BaseAddress = "myBaseUrl/"; diff --git a/docs/site/docs/test-doubles/index.md b/docs/site/docs/test-doubles/index.md index 88a1de589..033af3063 100644 --- a/docs/site/docs/test-doubles/index.md +++ b/docs/site/docs/test-doubles/index.md @@ -11,10 +11,10 @@ bUnit does, however, come with a few specially crafted test doubles for some of The built-in test doubles are described on the following pages: -- +- - - -- -- -- +- +- +- - \ No newline at end of file diff --git a/docs/site/docs/test-doubles/fake-navigation-manager.md b/docs/site/docs/test-doubles/navigation-manager.md similarity index 84% rename from docs/site/docs/test-doubles/fake-navigation-manager.md rename to docs/site/docs/test-doubles/navigation-manager.md index ab7f425f0..f4eb7ac00 100644 --- a/docs/site/docs/test-doubles/fake-navigation-manager.md +++ b/docs/site/docs/test-doubles/navigation-manager.md @@ -1,11 +1,11 @@ --- -uid: fake-navigation-manager -title: Faking NavigationManager +uid: bunit-navigation-manager +title: Adding NavigationManager --- -# Faking `NavigationManager` +# Adding `NavigationManager` -bUnit has a fake version of Blazor's `NavigationManager` built-in, which is added by default to bUnit's `TestContext.Services` service provider. That means nothing special is needed to test components that depend on `NavigationManager`, as it is already available by default. +bUnit has its own version of Blazor's `NavigationManager` built-in, which is added by default to bUnit's `TestContext.Services` service provider. That means nothing special is needed to test components that depend on `NavigationManager`, as it is already available by default. ## Verify `NavigationManager` interactions @@ -43,7 +43,7 @@ To verify that the `` component correctly listens to location c ```csharp // Arrange -var navMan = Services.GetRequiredService(); +var navMan = Services.GetRequiredService(); var cut = RenderComponent(); // Act - trigger a navigation change @@ -64,11 +64,11 @@ var cut = RenderComponent(parameters => parameters cut.Find("button").Click(); // Assert - inspect the navigation manager to see if its Uri has been updated. -var navMan = Services.GetRequiredService(); +var navMan = Services.GetRequiredService(); Assert.Equal("http://localhost/foo", navMan.Uri); ``` -If a component issues multiple `NavigateTo` calls, then it is possible to inspect the navigation history by accessing the property. It's a stack based structure, meaning the latest navigations will be first in the collection at index 0. +If a component issues multiple `NavigateTo` calls, then it is possible to inspect the navigation history by accessing the property. It's a stack based structure, meaning the latest navigations will be first in the collection at index 0. ## Asserting that navigation was prevented with the `NavigationLock` component @@ -93,7 +93,7 @@ A component can look like this: A typical test, which asserts that the navigation got prevented, would look like this: ```csharp -var navMan = Services.GetRequiredService(); +var navMan = Services.GetRequiredService(); var cut = RenderComponent(); cut.Find("button").Click(); @@ -123,7 +123,7 @@ As `` navigation is not natively supported in bUnit, the `NavigationMana The test utilizes the `NavigationManager` itself to achieve the same: ```csharp -var navMan = Services.GetRequiredService(); +var navMan = Services.GetRequiredService(); var cut = RenderComponent(); navMan.NavigateTo("/counter"); @@ -149,7 +149,7 @@ NavigationManager.NavigateToLogin("authentication/login", requestOptions); A test could look like this: ```csharp -var navigationManager = Services.GetRequiredService(); +var navigationManager = Services.GetRequiredService(); ActionToTriggerTheNavigationManager(); diff --git a/docs/site/docs/test-doubles/faking-persistentcomponentstate.md b/docs/site/docs/test-doubles/persistentcomponentstate.md similarity index 61% rename from docs/site/docs/test-doubles/faking-persistentcomponentstate.md rename to docs/site/docs/test-doubles/persistentcomponentstate.md index c03f78110..2c8f8ac4b 100644 --- a/docs/site/docs/test-doubles/faking-persistentcomponentstate.md +++ b/docs/site/docs/test-doubles/persistentcomponentstate.md @@ -1,52 +1,52 @@ --- -uid: faking-persistentcomponentstate -title: Faking persistent component state +uid: bunit-persistentcomponentstate +title: Adding persistent component state --- -# Faking persistent component state +# Adding persistent component state -bUnit comes with fake version of the `PersistentComponentState` type in Blazor that makes it possible to test components that use the type. +bUnit comes with its own version of the `PersistentComponentState` type in Blazor that makes it possible to test components that use the type. -## Using the fake `PersistentComponentState` +## Using the `PersistentComponentState` -To use the fake `PersistentComponentState` in bUnit, call the `AddFakePersistentComponentState` extension method on `TestContext`: +To use the `PersistentComponentState` in bUnit, call the `AddBunitPersistentComponentState` extension method on `TestContext`: ```csharp -var fakeState = AddFakePersistentComponentState(); +var state = AddBunitPersistentComponentState(); ``` -Calling `AddFakePersistentComponentState` returns a `FakePersistentComponentState` type, which has three methods; one to persist data, one to get persisted data, and one that triggers any "OnPersisting" callbacks added to the `PersistentComponentState`. +Calling `AddBunitPersistentComponentState` returns a `BunitPersistentComponentState` type, which has three methods; one to persist data, one to get persisted data, and one that triggers any "OnPersisting" callbacks added to the `PersistentComponentState`. To add data to the `PersistentComponentState` before running a test, i.e. to verify that a component uses the persisted state, use the `Persist` method: ```csharp -var fakeState = AddFakePersistentComponentState(); +var state = AddBunitPersistentComponentState(); var key = "STATE KEY"; var data = ...; // data to persist -fakeState.Persist(key, data); +state.Persist(key, data); // render component ``` -To trigger a callback registered with the `PersistentComponentState.RegisterOnPersisting` method, use the `TriggerOnPersisting` method on `FakePersistentComponentState`: +To trigger a callback registered with the `PersistentComponentState.RegisterOnPersisting` method, use the `TriggerOnPersisting` method on `BunitPersistentComponentState`: ```csharp -var fakeState = AddFakePersistentComponentState(); +var state = AddBunitPersistentComponentState(); // render component -fakeState.TriggerOnPersisting(); +state.TriggerOnPersisting(); ``` To check if data has been persisted, use the `TryTake` method: ```csharp -var fakeState = AddFakePersistentComponentState(); +var state = AddBunitPersistentComponentState(); var key = "STATE KEY"; // render component, call TriggerOnPersisting -bool foundState = fakeState.TryTake(key, out var data); +bool foundState = state.TryTake(key, out var data); ``` The following section has a complete example. @@ -91,14 +91,14 @@ In this example, lets test the following `` component that use `Persi } ``` -To test that the `` component uses persisted weather data instead of downloading (generating) it again with the `CreateForecastsAsync` method, use the `Persist` method on the `FakePersistentComponentState` type: +To test that the `` component uses persisted weather data instead of downloading (generating) it again with the `CreateForecastsAsync` method, use the `Persist` method on the `BunitPersistentComponentState` type: ```csharp // Arrange -var fakeState = AddFakePersistentComponentState(); +var state = AddBunitPersistentComponentState(); // Persist a single weather forecast with a temperature of 42 -fakeState.Persist("weather-data", new [] { new WeatherForecast { Temperature = 42 } }); +state.Persist("weather-data", new [] { new WeatherForecast { Temperature = 42 } }); // Act var cut = RenderComponent(); @@ -111,14 +111,14 @@ To test that the `` component correctly persists weather data when it ```csharp // Arrange -var fakeState = AddFakePersistentComponentState(); +var state = AddBunitPersistentComponentState(); var cut = RenderComponent(); // Act - trigger the FetchData components PersistForecasts method -fakeState.TriggerOnPersisting(); +state.TriggerOnPersisting(); // Assert that state was saved and there is a non-empty forecast array returned -var didSaveState = fakeState.TryTake("weather-data", out var savedState); +var didSaveState = state.TryTake("weather-data", out var savedState); Assert.IsTrue(didSaveState); Assert.NotEmpty(savedState); ``` diff --git a/docs/site/docs/toc.md b/docs/site/docs/toc.md index 327afde06..3b6644f46 100644 --- a/docs/site/docs/toc.md +++ b/docs/site/docs/toc.md @@ -23,12 +23,12 @@ # [Test doubles](xref:test-doubles) ## [Emulating IJSRuntime](xref:emulating-ijsruntime) -## [Faking authorization](xref:faking-auth) +## [Adding Authorization](xref:bunit-auth) ## [Mocking HttpClient](xref:mocking-httpclient) ## [Mocking Localizer](xref:mocking-localizer) -## [Faking PersistentComponentState](xref:faking-persistentcomponentstate) -## [Faking NavigationManager](xref:fake-navigation-manager) -## [Faking IWebAssemblyHostEnvironment](xref:fake-webassemblyhostenvironment) +## [Adding PersistentComponentState](xref:bunit-persistentcomponentstate) +## [Adding NavigationManager](xref:bunit-navigation-manager) +## [Adding IWebAssemblyHostEnvironment](xref:bunit-webassemblyhostenvironment) ## [Testing with InputFile component](xref:input-file) # [Extensions](xref:extensions) diff --git a/src/bunit/Extensions/TestServiceProviderExtensions.cs b/src/bunit/Extensions/TestServiceProviderExtensions.cs index 40fca7ba0..2041a48ff 100644 --- a/src/bunit/Extensions/TestServiceProviderExtensions.cs +++ b/src/bunit/Extensions/TestServiceProviderExtensions.cs @@ -30,19 +30,19 @@ public static IServiceCollection AddDefaultTestContextServices(this IServiceColl services.AddSingleton(); services.AddSingleton(); - // bUnits fake JSInterop + // bUnits JSInterop services.AddSingleton(jsInterop.JSRuntime); - // bUnits fake Navigation Manager - services.AddSingleton(); - services.AddSingleton(s => s.GetRequiredService()); - services.AddSingleton(); + // bUnits Navigation Manager + services.AddSingleton(); + services.AddSingleton(s => s.GetRequiredService()); + services.AddSingleton(); - // bUnits fake WebAssemblyHostEnvironment - services.AddSingleton(); - services.AddSingleton(s => s.GetRequiredService()); + // bUnits WebAssemblyHostEnvironment + services.AddSingleton(); + services.AddSingleton(s => s.GetRequiredService()); - // bUnits fake ScrollToLocationHash + // bUnits ScrollToLocationHash services.AddSingleton(); services.AddSupplyValueFromQueryProvider(); diff --git a/src/bunit/TestDoubles/Authorization/FakeAuthenticationStateProvider.cs b/src/bunit/TestDoubles/Authorization/BunitAuthenticationStateProvider.cs similarity index 90% rename from src/bunit/TestDoubles/Authorization/FakeAuthenticationStateProvider.cs rename to src/bunit/TestDoubles/Authorization/BunitAuthenticationStateProvider.cs index a077f1828..83afac68e 100644 --- a/src/bunit/TestDoubles/Authorization/FakeAuthenticationStateProvider.cs +++ b/src/bunit/TestDoubles/Authorization/BunitAuthenticationStateProvider.cs @@ -4,22 +4,22 @@ namespace Bunit.TestDoubles; /// -/// Represents a fake implementation of AuthenticationStateProvider for testing purposes that allows +/// Represents a implementation of AuthenticationStateProvider for testing purposes that allows /// user to test components that use authentication and authorization. /// -public class FakeAuthenticationStateProvider : AuthenticationStateProvider +public class BunitAuthenticationStateProvider : AuthenticationStateProvider { private TaskCompletionSource authState = new(); /// - /// Initializes a new instance of the class + /// Initializes a new instance of the class /// with an initial AuthenticationState. /// /// Identity's user name. /// Roles that this user principal has. /// Claims to add to user principal. /// The authentication type for the user principal. - public FakeAuthenticationStateProvider( + public BunitAuthenticationStateProvider( string userName, IEnumerable? roles = null, IEnumerable? claims = null, @@ -27,9 +27,9 @@ public FakeAuthenticationStateProvider( => SetAuthenticatedState(userName, roles, claims, authenticationType); /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - public FakeAuthenticationStateProvider() => SetUnauthenticatedState(); + public BunitAuthenticationStateProvider() => SetUnauthenticatedState(); /// /// Overridden method to get the current authentication state. @@ -114,7 +114,7 @@ private static AuthenticationState CreateAuthenticationState( { roles ??= Array.Empty(); claims ??= Array.Empty(); - authenticationType ??= "bUnit Fake Authentication"; + authenticationType ??= "bUnit Authentication"; var usernameClaim = new Claim(ClaimsIdentity.DefaultNameClaimType, username); var roleClaims = roles.Select(x => new Claim(ClaimsIdentity.DefaultRoleClaimType, x)); diff --git a/src/bunit/TestDoubles/Authorization/FakeAuthorizationExtensions.cs b/src/bunit/TestDoubles/Authorization/BunitAuthorizationExtensions.cs similarity index 79% rename from src/bunit/TestDoubles/Authorization/FakeAuthorizationExtensions.cs rename to src/bunit/TestDoubles/Authorization/BunitAuthorizationExtensions.cs index ed10641c4..82545ed28 100644 --- a/src/bunit/TestDoubles/Authorization/FakeAuthorizationExtensions.cs +++ b/src/bunit/TestDoubles/Authorization/BunitAuthorizationExtensions.cs @@ -7,21 +7,21 @@ namespace Bunit.TestDoubles; /// Helper methods for registering the Authentication/Authorization services with /// a . /// -public static class FakeAuthorizationExtensions +public static class BunitAuthorizationExtensions { /// /// Adds the appropriate Blazor authentication and authorization services to the to enable /// an authenticated user, as well as adding the component to the /// test contexts render tree. /// - public static TestAuthorizationContext AddTestAuthorization(this TestContextBase context) + public static TestAuthorizationContext AddAuthorization(this TestContextBase context) { ArgumentNullException.ThrowIfNull(context); context.RenderTree.TryAdd(); - context.Services.AddSingleton(); + context.Services.AddSingleton(); #pragma warning disable CS0618 - context.Services.AddSingleton(s => s.GetRequiredService()); + context.Services.AddSingleton(s => s.GetRequiredService()); #pragma warning restore CS0618 var authCtx = new TestAuthorizationContext(); authCtx.SetNotAuthorized(); diff --git a/src/bunit/TestDoubles/Authorization/FakeAuthorizationPolicyProvider.cs b/src/bunit/TestDoubles/Authorization/BunitAuthorizationPolicyProvider.cs similarity index 95% rename from src/bunit/TestDoubles/Authorization/FakeAuthorizationPolicyProvider.cs rename to src/bunit/TestDoubles/Authorization/BunitAuthorizationPolicyProvider.cs index 33d51685f..a20d361c5 100644 --- a/src/bunit/TestDoubles/Authorization/FakeAuthorizationPolicyProvider.cs +++ b/src/bunit/TestDoubles/Authorization/BunitAuthorizationPolicyProvider.cs @@ -6,7 +6,7 @@ namespace Bunit.TestDoubles; /// Test class that provides an implementation of IAuthorizationPolicyProvider that /// assists user in testing components that use authentication and authorization. ///
-public class FakeAuthorizationPolicyProvider : IAuthorizationPolicyProvider +public class BunitAuthorizationPolicyProvider : IAuthorizationPolicyProvider { private readonly AuthorizationOptions options = new(); private string policySchemeName = "TestScheme"; diff --git a/src/bunit/TestDoubles/Authorization/FakeAuthorizationService.cs b/src/bunit/TestDoubles/Authorization/BunitAuthorizationService.cs similarity index 94% rename from src/bunit/TestDoubles/Authorization/FakeAuthorizationService.cs rename to src/bunit/TestDoubles/Authorization/BunitAuthorizationService.cs index 928f697c5..189631880 100644 --- a/src/bunit/TestDoubles/Authorization/FakeAuthorizationService.cs +++ b/src/bunit/TestDoubles/Authorization/BunitAuthorizationService.cs @@ -10,17 +10,17 @@ namespace Bunit.TestDoubles; /// assists user in testing components by allowing them to set the authorization /// expected authorization response. ///
-public class FakeAuthorizationService : IAuthorizationService +public class BunitAuthorizationService : IAuthorizationService { private AuthorizationState currentState; private IEnumerable? supportedPolicies; private IEnumerable supportedRoles = Array.Empty(); /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// Initial authorization state. - public FakeAuthorizationService(AuthorizationState state = AuthorizationState.Authorized) + public BunitAuthorizationService(AuthorizationState state = AuthorizationState.Authorized) { currentState = state; } diff --git a/src/bunit/TestDoubles/Authorization/MissingFakeAuthorizationException.cs b/src/bunit/TestDoubles/Authorization/MissingBunitAuthorizationException.cs similarity index 62% rename from src/bunit/TestDoubles/Authorization/MissingFakeAuthorizationException.cs rename to src/bunit/TestDoubles/Authorization/MissingBunitAuthorizationException.cs index abbeef0b4..3598769f2 100644 --- a/src/bunit/TestDoubles/Authorization/MissingFakeAuthorizationException.cs +++ b/src/bunit/TestDoubles/Authorization/MissingBunitAuthorizationException.cs @@ -1,11 +1,11 @@ namespace Bunit.TestDoubles; /// -/// Exception used to indicate that the fake authorization services are required by a test +/// Exception used to indicate that the bunit authorization services are required by a test /// but provided in TestContext.Services. /// [Serializable] -public sealed class MissingFakeAuthorizationException : Exception +public sealed class MissingBunitAuthorizationException : Exception { /// /// Gets the invoking service name. @@ -13,18 +13,18 @@ public sealed class MissingFakeAuthorizationException : Exception public string ServiceName { get; } /// - /// Initializes a new instance of the class + /// Initializes a new instance of the class /// with the arguments used in the invocation. /// /// The service being used. - public MissingFakeAuthorizationException(string serviceName) + public MissingBunitAuthorizationException(string serviceName) : base($"This test requires {serviceName} to be supplied, because the component under test uses authentication/authorization during the test. You can fix this by calling TestContext.Services.AddAuthorization with appropriate values. More information can be found in the documentation.") { ServiceName = serviceName; - HelpLink = "https://bunit.egilhansen.com/docs/test-doubles/faking-auth"; + HelpLink = "https://bunit.egilhansen.com/docs/test-doubles/bunit-auth"; } - private MissingFakeAuthorizationException(SerializationInfo serializationInfo, StreamingContext streamingContext) + private MissingBunitAuthorizationException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { ServiceName = serializationInfo?.GetString(nameof(ServiceName)) ?? string.Empty; diff --git a/src/bunit/TestDoubles/Authorization/PlaceholderAuthenticationStateProvider.cs b/src/bunit/TestDoubles/Authorization/PlaceholderAuthenticationStateProvider.cs index 74df2cbf7..5a2df061e 100644 --- a/src/bunit/TestDoubles/Authorization/PlaceholderAuthenticationStateProvider.cs +++ b/src/bunit/TestDoubles/Authorization/PlaceholderAuthenticationStateProvider.cs @@ -6,6 +6,6 @@ internal sealed class PlaceholderAuthenticationStateProvider : AuthenticationSta { public override Task GetAuthenticationStateAsync() { - throw new MissingFakeAuthorizationException(nameof(AuthenticationStateProvider)); + throw new MissingBunitAuthorizationException(nameof(AuthenticationStateProvider)); } } diff --git a/src/bunit/TestDoubles/Authorization/PlaceholderAuthorizationService.cs b/src/bunit/TestDoubles/Authorization/PlaceholderAuthorizationService.cs index 527cd1c0e..e112a86fd 100644 --- a/src/bunit/TestDoubles/Authorization/PlaceholderAuthorizationService.cs +++ b/src/bunit/TestDoubles/Authorization/PlaceholderAuthorizationService.cs @@ -7,11 +7,11 @@ internal sealed class PlaceholderAuthorizationService : IAuthorizationService { public Task AuthorizeAsync(ClaimsPrincipal user, object? resource, IEnumerable requirements) { - throw new MissingFakeAuthorizationException(nameof(IAuthorizationService)); + throw new MissingBunitAuthorizationException(nameof(IAuthorizationService)); } public Task AuthorizeAsync(ClaimsPrincipal user, object? resource, string policyName) { - throw new MissingFakeAuthorizationException(nameof(IAuthorizationService)); + throw new MissingBunitAuthorizationException(nameof(IAuthorizationService)); } } diff --git a/src/bunit/TestDoubles/Authorization/TestAuthorizationContext.cs b/src/bunit/TestDoubles/Authorization/TestAuthorizationContext.cs index 994fe72e6..4594b8fd0 100644 --- a/src/bunit/TestDoubles/Authorization/TestAuthorizationContext.cs +++ b/src/bunit/TestDoubles/Authorization/TestAuthorizationContext.cs @@ -10,9 +10,9 @@ namespace Bunit.TestDoubles; /// public class TestAuthorizationContext { - private readonly FakeAuthorizationService authService = new(); - private readonly FakeAuthorizationPolicyProvider policyProvider = new(); - private readonly FakeAuthenticationStateProvider authProvider = new(); + private readonly BunitAuthorizationService authService = new(); + private readonly BunitAuthorizationPolicyProvider policyProvider = new(); + private readonly BunitAuthenticationStateProvider authProvider = new(); /// /// Gets a value indicating whether user is authenticated. diff --git a/src/bunit/TestDoubles/NavigationInterception/FakeNavigationInterception.cs b/src/bunit/TestDoubles/NavigationInterception/BunitNavigationInterception.cs similarity index 66% rename from src/bunit/TestDoubles/NavigationInterception/FakeNavigationInterception.cs rename to src/bunit/TestDoubles/NavigationInterception/BunitNavigationInterception.cs index 974e5dae0..f6f082bfc 100644 --- a/src/bunit/TestDoubles/NavigationInterception/FakeNavigationInterception.cs +++ b/src/bunit/TestDoubles/NavigationInterception/BunitNavigationInterception.cs @@ -2,7 +2,7 @@ namespace Bunit.TestDoubles; -internal sealed class FakeNavigationInterception : INavigationInterception +internal sealed class BunitNavigationInterception : INavigationInterception { public Task EnableNavigationInterceptionAsync() => Task.CompletedTask; } diff --git a/src/bunit/TestDoubles/NavigationManager/FakeNavigationManager.cs b/src/bunit/TestDoubles/NavigationManager/BunitNavigationManager.cs similarity index 86% rename from src/bunit/TestDoubles/NavigationManager/FakeNavigationManager.cs rename to src/bunit/TestDoubles/NavigationManager/BunitNavigationManager.cs index e8ccf1190..d4e19e2de 100644 --- a/src/bunit/TestDoubles/NavigationManager/FakeNavigationManager.cs +++ b/src/bunit/TestDoubles/NavigationManager/BunitNavigationManager.cs @@ -1,5 +1,4 @@ using System.Diagnostics; -using Bunit.Rendering; using Microsoft.AspNetCore.Components.Routing; namespace Bunit.TestDoubles; @@ -7,17 +6,17 @@ namespace Bunit.TestDoubles; using URI = Uri; /// -/// Represents a fake that captures calls to +/// Represents a that captures calls to /// for testing purposes. /// [DebuggerDisplay("Current Uri: {Uri}, History Count: {History.Count}")] -public sealed class FakeNavigationManager : NavigationManager +public sealed class BunitNavigationManager : NavigationManager { private readonly TestContextBase testContextBase; private readonly Stack history = new(); /// - /// The navigation history captured by the . + /// The navigation history captured by the . /// This is a stack based collection, so the first element is the latest/current navigation target. /// /// @@ -26,10 +25,10 @@ public sealed class FakeNavigationManager : NavigationManager public IReadOnlyCollection History => history; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - [SuppressMessage("Minor Code Smell", "S1075:URIs should not be hardcoded", Justification = "By design. Fake navigation manager defaults to local host as base URI.")] - public FakeNavigationManager(TestContextBase testContextBase) + [SuppressMessage("Minor Code Smell", "S1075:URIs should not be hardcoded", Justification = "By design. Bunit navigation manager defaults to local host as base URI.")] + public BunitNavigationManager(TestContextBase testContextBase) { this.testContextBase = testContextBase; Initialize("http://localhost/", "http://localhost/"); diff --git a/src/bunit/TestDoubles/NavigationManager/FakeSignOutSessionStateManager.cs b/src/bunit/TestDoubles/NavigationManager/BunitSignOutSessionStateManager.cs similarity index 67% rename from src/bunit/TestDoubles/NavigationManager/FakeSignOutSessionStateManager.cs rename to src/bunit/TestDoubles/NavigationManager/BunitSignOutSessionStateManager.cs index 8966e14be..66dc01802 100644 --- a/src/bunit/TestDoubles/NavigationManager/FakeSignOutSessionStateManager.cs +++ b/src/bunit/TestDoubles/NavigationManager/BunitSignOutSessionStateManager.cs @@ -3,11 +3,11 @@ namespace Bunit.TestDoubles; /// -/// Represents a fake that captures calls to +/// Represents bUnit's own that captures calls to /// that will help later to assert if the user was logged out /// #pragma warning disable CS0618 -public class FakeSignOutSessionStateManager : SignOutSessionStateManager +public class BunitSignOutSessionStateManager : SignOutSessionStateManager #pragma warning restore CS0618 { /// @@ -16,9 +16,9 @@ public class FakeSignOutSessionStateManager : SignOutSessionStateManager public bool IsSignedOut { get; set; } /// - /// Initializes a new instance of + /// Initializes a new instance of /// - public FakeSignOutSessionStateManager(IJSRuntime jsRuntime) : base(jsRuntime) + public BunitSignOutSessionStateManager(IJSRuntime jsRuntime) : base(jsRuntime) { } diff --git a/src/bunit/TestDoubles/PersistentComponentState/FakePersistentComponentState.cs b/src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentState.cs similarity index 87% rename from src/bunit/TestDoubles/PersistentComponentState/FakePersistentComponentState.cs rename to src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentState.cs index d10c717b3..c96b29ca6 100644 --- a/src/bunit/TestDoubles/PersistentComponentState/FakePersistentComponentState.cs +++ b/src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentState.cs @@ -5,27 +5,27 @@ namespace Bunit.TestDoubles; /// -/// Represents a fake , that can be used to the +/// Represents a , that can be used to the /// real in the Blazor runtime. /// -public sealed class FakePersistentComponentState +public sealed class BunitPersistentComponentState { private static readonly JsonSerializerOptions JsonSerializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, PropertyNameCaseInsensitive = true, }; - private readonly FakePersistentComponentStateStore store; + private readonly BunitPersistentComponentStateStore store; private readonly Lazy manager; private readonly Lazy renderer; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The to pull lazily dependencies from. - internal FakePersistentComponentState(IServiceProvider services) + internal BunitPersistentComponentState(IServiceProvider services) { - store = new FakePersistentComponentStateStore(); + store = new BunitPersistentComponentStateStore(); manager = new Lazy(() => services.GetRequiredService()); renderer = new Lazy(() => services.GetRequiredService().Renderer); } @@ -37,7 +37,7 @@ internal FakePersistentComponentState(IServiceProvider services) /// /// /// Only call this method after all services has been registered with the . - /// Calling this method will lookup dependencies of the + /// Calling this method will lookup dependencies of the /// from the , which means no other services can be registered after this point. /// public void TriggerOnPersisting() @@ -51,7 +51,7 @@ public void TriggerOnPersisting() /// /// /// Only call this method after all services has been registered with the . - /// Calling this method will lookup dependencies of the + /// Calling this method will lookup dependencies of the /// from the , which means no other services can be registered after this point. /// /// The type. @@ -71,7 +71,7 @@ public void Persist(string key, TValue instance) ///
/// /// Only call this method after all services has been registered with the . - /// Calling this method will lookup dependencies of the + /// Calling this method will lookup dependencies of the /// from the , which means no other services can be registered after this point. /// /// The key used to persist the instance. diff --git a/src/bunit/TestDoubles/PersistentComponentState/FakePersistentComponentStateStore.cs b/src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentStateStore.cs similarity index 85% rename from src/bunit/TestDoubles/PersistentComponentState/FakePersistentComponentStateStore.cs rename to src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentStateStore.cs index 15705494a..385988834 100644 --- a/src/bunit/TestDoubles/PersistentComponentState/FakePersistentComponentStateStore.cs +++ b/src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentStateStore.cs @@ -1,6 +1,6 @@ namespace Bunit.TestDoubles; -internal class FakePersistentComponentStateStore : IPersistentComponentStateStore +internal class BunitPersistentComponentStateStore : IPersistentComponentStateStore { private readonly Dictionary state = new(StringComparer.Ordinal); diff --git a/src/bunit/TestDoubles/PersistentComponentState/TestContextBaseExtensions.cs b/src/bunit/TestDoubles/PersistentComponentState/TestContextBaseExtensions.cs index 2ed1e3dbf..adaa05034 100644 --- a/src/bunit/TestDoubles/PersistentComponentState/TestContextBaseExtensions.cs +++ b/src/bunit/TestDoubles/PersistentComponentState/TestContextBaseExtensions.cs @@ -3,21 +3,21 @@ namespace Bunit.TestDoubles; /// -/// Extensions related to . +/// Extensions related to . /// public static class TestContextBaseExtensions { /// - /// Adds and returns a to the services of the . + /// Adds and returns a to the services of the . /// - /// The test context to add the to. - /// The added . - public static FakePersistentComponentState AddFakePersistentComponentState(this TestContextBase testContext) + /// The test context to add the to. + /// The added . + public static BunitPersistentComponentState AddBunitPersistentComponentState(this TestContextBase testContext) { ArgumentNullException.ThrowIfNull(testContext); testContext.Services.AddSingleton(); testContext.Services.AddSingleton(s => s.GetRequiredService().State); - return new FakePersistentComponentState(testContext.Services); + return new BunitPersistentComponentState(testContext.Services); } } diff --git a/src/bunit/TestDoubles/WebAssemblyHostEnvironment/FakeWebAssemblyHostEnvironment.cs b/src/bunit/TestDoubles/WebAssemblyHostEnvironment/BunitWebAssemblyHostEnvironment.cs similarity index 81% rename from src/bunit/TestDoubles/WebAssemblyHostEnvironment/FakeWebAssemblyHostEnvironment.cs rename to src/bunit/TestDoubles/WebAssemblyHostEnvironment/BunitWebAssemblyHostEnvironment.cs index 6cdad1698..aca79cfa9 100644 --- a/src/bunit/TestDoubles/WebAssemblyHostEnvironment/FakeWebAssemblyHostEnvironment.cs +++ b/src/bunit/TestDoubles/WebAssemblyHostEnvironment/BunitWebAssemblyHostEnvironment.cs @@ -3,9 +3,9 @@ namespace Bunit.TestDoubles; /// -/// Represents a fake that makes the and settable. +/// Represents bUnit's own that makes the and settable. /// -public class FakeWebAssemblyHostEnvironment : IWebAssemblyHostEnvironment +public class BunitWebAssemblyHostEnvironment : IWebAssemblyHostEnvironment { /// /// Gets or sets the name of the environment. Default is Production. @@ -40,5 +40,4 @@ public void SetEnvironmentToProduction() { Environment = "Production"; } - } diff --git a/tests/bunit.tests/TestDoubles/Authorization/AuthorizationTest.cs b/tests/bunit.tests/TestDoubles/Authorization/AuthorizationTest.cs index caeb410a2..95acc7bff 100644 --- a/tests/bunit.tests/TestDoubles/Authorization/AuthorizationTest.cs +++ b/tests/bunit.tests/TestDoubles/Authorization/AuthorizationTest.cs @@ -14,7 +14,7 @@ public AuthorizationTest(ITestOutputHelper outputHelper) public void Test001() { // Arrange - this.AddTestAuthorization(); + this.AddAuthorization(); // Act var cut = RenderComponent(); @@ -27,7 +27,7 @@ public void Test001() public void Test002() { // arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TestUser", AuthorizationState.Authorized); // act @@ -41,7 +41,7 @@ public void Test002() public void Test003() { // arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TestUser", AuthorizationState.Unauthorized); // act @@ -56,7 +56,7 @@ public void Test003() public async Task Test004() { // arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); // start off unauthenticated. var cut = RenderComponent(); @@ -76,7 +76,7 @@ public async Task Test004() public void Test004_Sync() { // arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); // start off unauthenticated. var cut = RenderComponent(); @@ -95,7 +95,7 @@ public void Test004_Sync() public void Test005() { // arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TestUser005", AuthorizationState.Authorized); // start off unauthenticated. @@ -115,18 +115,18 @@ public void Test005() public void Test006() { // act - var ex = Assert.Throws(() => RenderComponent()); + var ex = Assert.Throws(() => RenderComponent()); // assert Assert.Equal("AuthenticationStateProvider", ex.ServiceName); - Assert.Equal("https://bunit.egilhansen.com/docs/test-doubles/faking-auth", ex.HelpLink); + Assert.Equal("https://bunit.egilhansen.com/docs/test-doubles/bunit-auth", ex.HelpLink); } [Fact(DisplayName = "AuthorizeView with set policy with authenticated and authorized user")] public void Test007() { // arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TestUser").SetPolicies("ContentViewer"); // act @@ -140,7 +140,7 @@ public void Test007() public void Test008() { // arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TestUser"); // act @@ -154,7 +154,7 @@ public void Test008() public void Test0081() { // arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TestUser").SetPolicies("OtherPolicy"); // act @@ -168,7 +168,7 @@ public void Test0081() public void Test009() { // arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TestUser").SetRoles("Admin"); // act @@ -182,7 +182,7 @@ public void Test009() public void Test010() { // arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TestUser"); // act @@ -196,7 +196,7 @@ public void Test010() public void Test011() { // arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TestUser").SetRoles("NotAdmin"); // act @@ -210,7 +210,7 @@ public void Test011() public void Test012() { // arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorizing(); // act @@ -225,7 +225,7 @@ public void Test013() { // arrange var userId = new Guid("{5d5fa9c1-abf9-4ed6-8fb0-3365382b629c}"); - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); var emailClaim = new Claim(ClaimTypes.Email, "user@test.com"); var uuidClaim = new Claim(ClaimTypes.Sid, userId.ToString()); authContext.SetAuthorized("TestUser").SetClaims(uuidClaim, emailClaim); @@ -244,7 +244,7 @@ public void Test013() public void Test014() { // arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TestUser"); // act @@ -259,7 +259,7 @@ public void Test014() public void Test020() { var role = "myTestRole"; - var authCtx = this.AddTestAuthorization(); + var authCtx = this.AddAuthorization(); authCtx.SetAuthorized("FooBar"); authCtx.SetRoles(role); @@ -272,7 +272,7 @@ public void Test020() public void Test021() { // arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TestUser"); authContext.SetAuthenticationType("custom-auth-type"); @@ -287,7 +287,7 @@ public void Test021() public void Test022() { // arrange - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("TestUser"); // act diff --git a/tests/bunit.tests/TestDoubles/Authorization/FakeAuthenticationStateProviderTest.cs b/tests/bunit.tests/TestDoubles/Authorization/BunitAuthenticationStateProviderTest.cs similarity index 85% rename from tests/bunit.tests/TestDoubles/Authorization/FakeAuthenticationStateProviderTest.cs rename to tests/bunit.tests/TestDoubles/Authorization/BunitAuthenticationStateProviderTest.cs index f96ed2e7a..d00400a40 100644 --- a/tests/bunit.tests/TestDoubles/Authorization/FakeAuthenticationStateProviderTest.cs +++ b/tests/bunit.tests/TestDoubles/Authorization/BunitAuthenticationStateProviderTest.cs @@ -1,6 +1,6 @@ namespace Bunit.TestDoubles.Authorization; -public class FakeAuthenticationStateProviderTest +public class BunitAuthenticationStateProviderTest { [Fact(DisplayName = "Create authenticated AuthenticationState")] public async Task Test001() @@ -9,7 +9,7 @@ public async Task Test001() var roles = new List { "User" }; // act - var authProvider = new FakeAuthenticationStateProvider("TestUser", roles); + var authProvider = new BunitAuthenticationStateProvider("TestUser", roles); var authState = await authProvider.GetAuthenticationStateAsync(); // assert @@ -23,7 +23,7 @@ public async Task Test001() public async Task Test002() { // act - var authProvider = new FakeAuthenticationStateProvider(); + var authProvider = new BunitAuthenticationStateProvider(); var authState = await authProvider.GetAuthenticationStateAsync(); // assert @@ -37,7 +37,7 @@ public async Task Test002() public async Task Test003() { // arrange - var authProvider = new FakeAuthenticationStateProvider(); + var authProvider = new BunitAuthenticationStateProvider(); var stateChangeHandled = false; authProvider.AuthenticationStateChanged += _ => stateChangeHandled = true; diff --git a/tests/bunit.tests/TestDoubles/Authorization/FakeAuthorizationPolicyProviderTest.cs b/tests/bunit.tests/TestDoubles/Authorization/BunitAuthorizationPolicyProviderTest.cs similarity index 85% rename from tests/bunit.tests/TestDoubles/Authorization/FakeAuthorizationPolicyProviderTest.cs rename to tests/bunit.tests/TestDoubles/Authorization/BunitAuthorizationPolicyProviderTest.cs index 25897b285..14608a853 100644 --- a/tests/bunit.tests/TestDoubles/Authorization/FakeAuthorizationPolicyProviderTest.cs +++ b/tests/bunit.tests/TestDoubles/Authorization/BunitAuthorizationPolicyProviderTest.cs @@ -2,13 +2,13 @@ namespace Bunit.TestDoubles.Authorization; -public class FakeAuthorizationPolicyProviderTest +public class BunitAuthorizationPolicyProviderTest { [Fact(DisplayName = "Get default policy from PolicyProvider.")] public async Task Test001() { // arrange - var provider = new FakeAuthorizationPolicyProvider(); + var provider = new BunitAuthorizationPolicyProvider(); // act var policy = await provider.GetDefaultPolicyAsync(); @@ -24,7 +24,7 @@ public async Task Test001() public async Task Test002() { // arrange - var provider = new FakeAuthorizationPolicyProvider(); + var provider = new BunitAuthorizationPolicyProvider(); // act var policy = await provider.GetFallbackPolicyAsync(); @@ -37,7 +37,7 @@ public async Task Test002() public async Task Test003() { // arrange - var provider = new FakeAuthorizationPolicyProvider(); + var provider = new BunitAuthorizationPolicyProvider(); provider.SetPolicyScheme("TestScheme"); // act @@ -55,7 +55,7 @@ public async Task Test003() public async Task Test004() { // arrange - var provider = new FakeAuthorizationPolicyProvider(); + var provider = new BunitAuthorizationPolicyProvider(); provider.SetPolicyScheme("TestScheme"); // act @@ -73,7 +73,7 @@ public async Task Test004() public void Test006() { // arrange - var provider = new FakeAuthorizationPolicyProvider(); + var provider = new BunitAuthorizationPolicyProvider(); // assert Assert.Throws( diff --git a/tests/bunit.tests/TestDoubles/Authorization/FakeAuthorizationServiceTest.cs b/tests/bunit.tests/TestDoubles/Authorization/BunitAuthorizationServiceTest.cs similarity index 83% rename from tests/bunit.tests/TestDoubles/Authorization/FakeAuthorizationServiceTest.cs rename to tests/bunit.tests/TestDoubles/Authorization/BunitAuthorizationServiceTest.cs index 92df5a123..fcef20f4e 100644 --- a/tests/bunit.tests/TestDoubles/Authorization/FakeAuthorizationServiceTest.cs +++ b/tests/bunit.tests/TestDoubles/Authorization/BunitAuthorizationServiceTest.cs @@ -3,13 +3,13 @@ namespace Bunit.TestDoubles.Authorization; -public class FakeAuthorizationServiceTest +public class BunitAuthorizationServiceTest { [Fact(DisplayName = "Get AuthorizeAsync with an authorized result.")] public async Task Test002() { // arrange - var service = new FakeAuthorizationService(AuthorizationState.Unauthorized); + var service = new BunitAuthorizationService(AuthorizationState.Unauthorized); var user = CreateUserPrincipal("FooBar"); var requirements = new List(); @@ -25,7 +25,7 @@ public async Task Test002() public async Task Test003() { // arrange - var service = new FakeAuthorizationService(); + var service = new BunitAuthorizationService(); var user = CreateUserPrincipal("FooBar"); var requirements = new List(); @@ -41,7 +41,7 @@ public async Task Test003() public async Task Test004() { // arrange - var service = new FakeAuthorizationService(AuthorizationState.Unauthorized); + var service = new BunitAuthorizationService(AuthorizationState.Unauthorized); var user = CreateUserPrincipal("FooBar"); // act @@ -61,7 +61,7 @@ public async Task Test005() var requirements = Array.Empty(); // act - var ex = await Assert.ThrowsAsync(() => + var ex = await Assert.ThrowsAsync(() => authService.AuthorizeAsync(null!, string.Empty, requirements)); // assert @@ -76,7 +76,7 @@ public async Task Test006() var authService = ctx.Services.GetRequiredService(); // act - var ex = await Assert.ThrowsAsync(() => + var ex = await Assert.ThrowsAsync(() => authService.AuthorizeAsync(default!, string.Empty, "testPolicy")); // assert @@ -86,7 +86,7 @@ public async Task Test006() private static ClaimsPrincipal CreateUserPrincipal(string username) { var usernameClaim = new Claim(ClaimsIdentity.DefaultNameClaimType, username); - var identity = new ClaimsIdentity(claims: new[] { usernameClaim }, authenticationType: "bUnit Fake Authentication"); + var identity = new ClaimsIdentity(claims: new[] { usernameClaim }, authenticationType: "bUnit Authentication"); return new ClaimsPrincipal(identity); } } diff --git a/tests/bunit.tests/TestDoubles/Authorization/TestAuthorizationContextTest.cs b/tests/bunit.tests/TestDoubles/Authorization/TestAuthorizationContextTest.cs index 74da5968e..63917997d 100644 --- a/tests/bunit.tests/TestDoubles/Authorization/TestAuthorizationContextTest.cs +++ b/tests/bunit.tests/TestDoubles/Authorization/TestAuthorizationContextTest.cs @@ -6,7 +6,7 @@ public class TestAuthorizationContextTest : TestContext public void Test003() { // act - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); // assert Assert.False(authContext.IsAuthenticated); @@ -19,7 +19,7 @@ public void Test003() public void Test0031() { // act - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorizing(); // assert @@ -33,7 +33,7 @@ public void Test0031() public void Test002() { // act - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("DarthPedro", AuthorizationState.Unauthorized); // assert @@ -47,7 +47,7 @@ public void Test002() public void Test0010() { // act - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("DarthPedro"); // assert @@ -61,7 +61,7 @@ public void Test0010() public void Test001() { // act - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("DarthPedro"); authContext.SetRoles("some-role"); @@ -76,7 +76,7 @@ public void Test001() public void Test0011() { // act - var authContext = this.AddTestAuthorization(); + var authContext = this.AddAuthorization(); authContext.SetAuthorized("DarthPedro"); authContext.SetPolicies("TestPolicy", "Other"); diff --git a/tests/bunit.tests/TestDoubles/FakeSignOutSessionStateManagerTest.cs b/tests/bunit.tests/TestDoubles/BunitSignOutSessionStateManagerTest.cs similarity index 64% rename from tests/bunit.tests/TestDoubles/FakeSignOutSessionStateManagerTest.cs rename to tests/bunit.tests/TestDoubles/BunitSignOutSessionStateManagerTest.cs index 8622ea081..865a57bcf 100644 --- a/tests/bunit.tests/TestDoubles/FakeSignOutSessionStateManagerTest.cs +++ b/tests/bunit.tests/TestDoubles/BunitSignOutSessionStateManagerTest.cs @@ -1,16 +1,16 @@ namespace Bunit.TestDoubles; -public class FakeSignOutSessionStateManagerTest : TestContext +public class BunitSignOutSessionStateManagerTest : TestContext { [Theory, AutoData] public void ShouldSignOut(string randomUserName) { - this.AddTestAuthorization().SetAuthorized(randomUserName); + this.AddAuthorization().SetAuthorized(randomUserName); var cut = RenderComponent(); cut.Find("button").Click(); - Services.GetService()! + Services.GetService()! .IsSignedOut .ShouldBeTrue(); } @@ -18,7 +18,7 @@ public void ShouldSignOut(string randomUserName) [Fact] public async Task ShouldReturnSignOutStateOnValidateSignOutState() { - var cut = new FakeSignOutSessionStateManager(Substitute.For()); + var cut = new BunitSignOutSessionStateManager(Substitute.For()); await cut.SetSignOutState(); var wasValidate = await cut.ValidateSignOutState(); diff --git a/tests/bunit.tests/TestDoubles/FakeWebAssemblyHostEnvironmentTest.cs b/tests/bunit.tests/TestDoubles/BunitWebAssemblyHostEnvironmentTest.cs similarity index 73% rename from tests/bunit.tests/TestDoubles/FakeWebAssemblyHostEnvironmentTest.cs rename to tests/bunit.tests/TestDoubles/BunitWebAssemblyHostEnvironmentTest.cs index b246aa38f..182023b4f 100644 --- a/tests/bunit.tests/TestDoubles/FakeWebAssemblyHostEnvironmentTest.cs +++ b/tests/bunit.tests/TestDoubles/BunitWebAssemblyHostEnvironmentTest.cs @@ -1,11 +1,11 @@ namespace Bunit.TestDoubles; -public class FakeWebAssemblyHostEnvironmentTest : TestContext +public class BunitWebAssemblyHostEnvironmentTest : TestContext { [Fact] public void ShouldSayHelloToDevelopers() { - var hostEnvironment = Services.GetRequiredService(); + var hostEnvironment = Services.GetRequiredService(); hostEnvironment.SetEnvironmentToDevelopment(); var cut = RenderComponent(); @@ -17,7 +17,7 @@ public void ShouldSayHelloToDevelopers() [Fact] public void ShouldUseCorrectBaseAddress() { - var hostEnvironment = Services.GetRequiredService(); + var hostEnvironment = Services.GetRequiredService(); hostEnvironment.BaseAddress = "myBaseUrl/"; var cut = RenderComponent(); diff --git a/tests/bunit.tests/TestDoubles/NavigationManager/FakeNavigationInterceptionTest.cs b/tests/bunit.tests/TestDoubles/NavigationManager/BunitNavigationInterceptionTest.cs similarity index 77% rename from tests/bunit.tests/TestDoubles/NavigationManager/FakeNavigationInterceptionTest.cs rename to tests/bunit.tests/TestDoubles/NavigationManager/BunitNavigationInterceptionTest.cs index 16553b021..629da5514 100644 --- a/tests/bunit.tests/TestDoubles/NavigationManager/FakeNavigationInterceptionTest.cs +++ b/tests/bunit.tests/TestDoubles/NavigationManager/BunitNavigationInterceptionTest.cs @@ -1,11 +1,11 @@ namespace Bunit.TestDoubles; -public class FakeNavigationInterceptionTest +public class BunitNavigationInterceptionTest { [Fact(DisplayName = "EnableNavigationInterceptionAsync returns completed task")] public void Test001() { - new FakeNavigationInterception() + new BunitNavigationInterception() .EnableNavigationInterceptionAsync() .IsCompletedSuccessfully .ShouldBeTrue(); @@ -16,6 +16,6 @@ public void Test002() { using var ctx = new TestContext(); ctx.Services.GetService() - .ShouldBeOfType(); + .ShouldBeOfType(); } } diff --git a/tests/bunit.tests/TestDoubles/NavigationManager/FakeNavigationManagerTest.cs b/tests/bunit.tests/TestDoubles/NavigationManager/BunitNavigationManagerTest.cs similarity index 80% rename from tests/bunit.tests/TestDoubles/NavigationManager/FakeNavigationManagerTest.cs rename to tests/bunit.tests/TestDoubles/NavigationManager/BunitNavigationManagerTest.cs index 2c74eef40..453dcf902 100644 --- a/tests/bunit.tests/TestDoubles/NavigationManager/FakeNavigationManagerTest.cs +++ b/tests/bunit.tests/TestDoubles/NavigationManager/BunitNavigationManagerTest.cs @@ -5,26 +5,26 @@ namespace Bunit.TestDoubles; using static Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers; -public class FakeNavigationManagerTest : TestContext +public class BunitNavigationManagerTest : TestContext { - private FakeNavigationManager CreateFakeNavigationManager() - => Services.GetRequiredService(); + private BunitNavigationManager CreateNavigationManager() + => Services.GetRequiredService(); - [Fact(DisplayName = "TestContext.Services has NavigationManager registered by default as FakeNavigationManager")] + [Fact(DisplayName = "TestContext.Services has NavigationManager registered by default as BunitNavigationManager")] public void Test001() { var nm = Services.GetService(); - var fnm = Services.GetService(); + var fnm = Services.GetService(); nm.ShouldNotBeNull(); fnm.ShouldNotBeNull(); nm.ShouldBe(fnm); } - [Fact(DisplayName = "FakeNavigationManager.BaseUrl is set to http://localhost/")] + [Fact(DisplayName = "BunitNavigationManager.BaseUrl is set to http://localhost/")] public void Test002() { - var sut = CreateFakeNavigationManager(); + var sut = CreateNavigationManager(); sut.BaseUri.ShouldBe("http://localhost/"); } @@ -37,7 +37,7 @@ public void Test002() [InlineData("/#åäö")] public void Test003(string uri) { - var sut = CreateFakeNavigationManager(); + var sut = CreateNavigationManager(); var expectedUri = new Uri(new Uri(sut.BaseUri, UriKind.Absolute), new Uri(uri, UriKind.Relative)); sut.NavigateTo(uri); @@ -51,7 +51,7 @@ public void Test003(string uri) [InlineData("http://localhost/foo")] public void Test004(string uri) { - var sut = CreateFakeNavigationManager(); + var sut = CreateNavigationManager(); var expectedUri = new Uri(uri, UriKind.Absolute); sut.NavigateTo(uri); @@ -67,7 +67,7 @@ public void Test005() // arrange LocationChangedEventArgs actualLocationChange = default; var navigationUri = "foo"; - var sut = CreateFakeNavigationManager(); + var sut = CreateNavigationManager(); sut.LocationChanged += Sut_LocationChanged; // act @@ -87,7 +87,7 @@ void Sut_LocationChanged(object? sender, LocationChangedEventArgs e) [Fact(DisplayName = "LocationChanged is raised on the test renderer's dispatcher")] public void Test006() { - var sut = CreateFakeNavigationManager(); + var sut = CreateNavigationManager(); var cut = RenderComponent(); sut.NavigateTo("foo"); @@ -98,23 +98,23 @@ public void Test006() [Fact(DisplayName = "Uri should not be unescaped")] public void Test007() { - var sut = CreateFakeNavigationManager(); + var sut = CreateNavigationManager(); sut.NavigateTo("/with%20whitespace"); sut.Uri.ShouldEndWith("with%20whitespace"); } - + [Theory(DisplayName = "NavigateTo(uri, forceLoad, replaceHistoryEntry) is saved in history")] [InlineData("/uri", false, false)] [InlineData("/uri", true, false)] [InlineData("/uri", false, true)] public void Test200(string uri, bool forceLoad, bool replaceHistoryEntry) { - var sut = CreateFakeNavigationManager(); + var sut = CreateNavigationManager(); sut.NavigateTo(uri, forceLoad, replaceHistoryEntry); - + var navigationOptions = new NavigationOptions { ForceLoad = forceLoad, ReplaceHistoryEntry = replaceHistoryEntry }; sut.History.ShouldHaveSingleItem() @@ -124,7 +124,7 @@ public void Test200(string uri, bool forceLoad, bool replaceHistoryEntry) [Fact(DisplayName = "NavigateTo with replaceHistoryEntry true replaces previous history entry")] public void Test201() { - var sut = CreateFakeNavigationManager(); + var sut = CreateNavigationManager(); sut.NavigateTo("/firstUrl"); sut.NavigateTo("/secondUrl", new NavigationOptions { ReplaceHistoryEntry = true }); @@ -141,7 +141,7 @@ public void Test201() public void Test008() { const string externalUri = "https://bunit.dev/docs/getting-started/index.html"; - var sut = CreateFakeNavigationManager(); + var sut = CreateNavigationManager(); sut.NavigateTo(externalUri); @@ -154,7 +154,7 @@ public void Test009() { var locationChangedInvoked = false; const string externalUri = "https://bunit.dev/docs/getting-started/index.html"; - var sut = CreateFakeNavigationManager(); + var sut = CreateNavigationManager(); sut.LocationChanged += (s, e) => locationChangedInvoked = true; sut.NavigateTo(externalUri); @@ -162,38 +162,38 @@ public void Test009() locationChangedInvoked.ShouldBeFalse(); } - [Fact(DisplayName = "When component provides NavigationLock, FakeNavigationManager should intercept calls")] + [Fact(DisplayName = "When component provides NavigationLock, BunitNavigationManager should intercept calls")] public void Test010() { - var fakeNavigationManager = CreateFakeNavigationManager(); + var navigationManager = CreateNavigationManager(); var cut = RenderComponent(); cut.Find("button").Click(); cut.Instance.NavigationIntercepted.ShouldBeTrue(); - fakeNavigationManager.History.Single().State.ShouldBe(NavigationState.Prevented); + navigationManager.History.Single().State.ShouldBe(NavigationState.Prevented); } [Fact(DisplayName = "Intercepting external url's should work")] public void Test011() { - var fakeNavigationManager = CreateFakeNavigationManager(); + var navigationManager = CreateNavigationManager(); var cut = RenderComponent(); cut.Find("button").Click(); - fakeNavigationManager.History.ShouldNotBeEmpty(); + navigationManager.History.ShouldNotBeEmpty(); } - [Fact(DisplayName = "Exception while intercepting is set on FakeNaviationManager")] + [Fact(DisplayName = "Exception while intercepting is set on BunitNaviationManager")] public void Test012() { - var fakeNavigationManager = CreateFakeNavigationManager(); + var navigationManager = CreateNavigationManager(); var cut = RenderComponent(); cut.Find("button").Click(); - var entry = fakeNavigationManager.History.Single(); + var entry = navigationManager.History.Single(); entry.Exception.ShouldBeOfType(); entry.State.ShouldBe(NavigationState.Faulted); } @@ -201,16 +201,16 @@ public void Test012() [Fact(DisplayName = "StateFromJson deserialize InteractiveRequestOptions")] public void Test013() { - var fakeNavigationManager = CreateFakeNavigationManager(); + var navigationManager = CreateNavigationManager(); var requestOptions = new InteractiveRequestOptions { ReturnUrl = "return", Interaction = InteractionType.SignIn, }; requestOptions.TryAddAdditionalParameter("library", "bunit"); - fakeNavigationManager.NavigateToLogin("/some-url", requestOptions); + navigationManager.NavigateToLogin("/some-url", requestOptions); - var options = fakeNavigationManager.History.Last().StateFromJson(); + var options = navigationManager.History.Last().StateFromJson(); options.ShouldNotBeNull(); options.Interaction.ShouldBe(InteractionType.SignIn); options.ReturnUrl.ShouldBe("return"); @@ -221,40 +221,40 @@ public void Test013() [Fact(DisplayName = "Given no content in state then StateFromJson throws")] public void Test014() { - var fakeNavigationManager = CreateFakeNavigationManager(); - fakeNavigationManager.NavigateTo("/some-url"); + var navigationManager = CreateNavigationManager(); + navigationManager.NavigateTo("/some-url"); Should.Throw( - () => fakeNavigationManager.History.Last().StateFromJson()); + () => navigationManager.History.Last().StateFromJson()); } [Fact(DisplayName = "StateFromJson with invalid json throws")] public void Test015() { - var fakeNavigationManager = CreateFakeNavigationManager(); + var navigationManager = CreateNavigationManager(); - fakeNavigationManager.NavigateTo("/login", new NavigationOptions { HistoryEntryState = "" }); + navigationManager.NavigateTo("/login", new NavigationOptions { HistoryEntryState = "" }); Should.Throw( - () => fakeNavigationManager.History.Last().StateFromJson()); + () => navigationManager.History.Last().StateFromJson()); } - + [Fact(DisplayName = "Navigate to url with state should set that state on the NavigationManager")] public void Test016() { const string State = "State"; - var sut = CreateFakeNavigationManager(); + var sut = CreateNavigationManager(); sut.NavigateTo("/internal", new NavigationOptions { HistoryEntryState = State }); sut.HistoryEntryState.ShouldBe(State); } - + [Fact(DisplayName = "Navigate to url with force reload resets state")] public void Test017() { const string State = "State"; - var sut = CreateFakeNavigationManager(); + var sut = CreateNavigationManager(); sut.NavigateTo("/internal", new NavigationOptions { HistoryEntryState = State }); sut.NavigateTo("/internal", new NavigationOptions { HistoryEntryState = State, ForceLoad = true}); diff --git a/tests/bunit.tests/TestDoubles/PersistentComponentState/FakePersistentComponentStateTest.cs b/tests/bunit.tests/TestDoubles/PersistentComponentState/BunitPersistentComponentStateTest.cs similarity index 58% rename from tests/bunit.tests/TestDoubles/PersistentComponentState/FakePersistentComponentStateTest.cs rename to tests/bunit.tests/TestDoubles/PersistentComponentState/BunitPersistentComponentStateTest.cs index dc45b2c52..306760a11 100644 --- a/tests/bunit.tests/TestDoubles/PersistentComponentState/FakePersistentComponentStateTest.cs +++ b/tests/bunit.tests/TestDoubles/PersistentComponentState/BunitPersistentComponentStateTest.cs @@ -1,26 +1,26 @@ namespace Bunit.TestDoubles; -public class FakePersistentComponentStateTest : TestContext +public class BunitPersistentComponentStateTest : TestContext { - public FakePersistentComponentStateTest(ITestOutputHelper outputHelper) + public BunitPersistentComponentStateTest(ITestOutputHelper outputHelper) { Services.AddXunitLogger(outputHelper); } - [Fact(DisplayName = "AddFakePersistentComponentState is registers PersistentComponentState in services")] + [Fact(DisplayName = "AddBunitPersistentComponentState is registers PersistentComponentState in services")] public void Test001() { - _ = this.AddFakePersistentComponentState(); + _ = this.AddBunitPersistentComponentState(); var actual = Services.GetService(); actual.ShouldNotBeNull(); } - [Fact(DisplayName = "AddFakePersistentComponentState enables PersistentComponentState injection into components")] + [Fact(DisplayName = "AddBunitPersistentComponentState enables PersistentComponentState injection into components")] public void Test002() { - this.AddFakePersistentComponentState(); + this.AddBunitPersistentComponentState(); var cut = RenderComponent(); @@ -31,9 +31,9 @@ public void Test002() [AutoData] public void Test011(string key, string data) { - var fakeState = this.AddFakePersistentComponentState(); + var state = this.AddBunitPersistentComponentState(); - fakeState.Persist(key, data); + state.Persist(key, data); var store = Services.GetService(); store.TryTakeFromJson(key, out var actual).ShouldBeTrue(); @@ -43,12 +43,12 @@ public void Test011(string key, string data) [Fact(DisplayName = "TryTake returns true if key contains data saved in store")] public void Test012() { - var fakeState = this.AddFakePersistentComponentState(); + var state = this.AddBunitPersistentComponentState(); var cut = RenderComponent(); - fakeState.TriggerOnPersisting(); + state.TriggerOnPersisting(); - fakeState.TryTake(PersistentComponentStateSample.PersistenceKey, out var actual).ShouldBeTrue(); + state.TryTake(PersistentComponentStateSample.PersistenceKey, out var actual).ShouldBeTrue(); actual.ShouldBeEquivalentTo(cut.Instance.Forecasts); } @@ -56,16 +56,16 @@ public void Test012() [AutoData] public void Test013(string key) { - var fakeState = this.AddFakePersistentComponentState(); + var state = this.AddBunitPersistentComponentState(); - fakeState.TryTake(key, out var actual).ShouldBeFalse(); + state.TryTake(key, out _).ShouldBeFalse(); } [Fact(DisplayName = "TriggerOnPersisting triggers OnPersisting callbacks added to store")] public void Test014() { var onPersistingCalledTimes = 0; - var fakeState = this.AddFakePersistentComponentState(); + var state = this.AddBunitPersistentComponentState(); var store = Services.GetService(); store.RegisterOnPersisting(() => { @@ -73,7 +73,7 @@ public void Test014() return Task.CompletedTask; }); - fakeState.TriggerOnPersisting(); + state.TriggerOnPersisting(); onPersistingCalledTimes.ShouldBe(1); } From 98328a91ec876c82185cdbed1434007c4d95d546 Mon Sep 17 00:00:00 2001 From: Steven Giesel Date: Sun, 3 Mar 2024 11:11:12 +0100 Subject: [PATCH 09/42] refactor: Merge TestContext with TestContextBase --- MIGRATION.md | 3 + .../CustomServiceProviderFactoryUsage.cs | 12 +- .../docs/interaction/dispose-components.md | 4 +- .../docs/providing-input/root-render-tree.md | 2 +- docs/site/docs/test-doubles/auth.md | 4 +- .../InstanceComponentFactory{TComponent}.cs | 2 +- .../Internal/AngleSharpExtensions.cs | 6 +- .../RenderedComponentRenderExtensions.cs | 2 +- .../Extensions/RenderedFragmentExtensions.cs | 4 +- .../RenderedFragmentInvokeAsyncExtensions.cs | 8 +- ...ions.cs => TestContextRenderExtensions.cs} | 12 +- .../TestServiceProviderExtensions.cs | 2 +- .../WaitForHelpers/WaitForHelper.cs | 4 +- .../Rendering/BunitComponentActivator.cs | 2 +- src/bunit/Rendering/BunitHtmlParser.cs | 2 +- src/bunit/TestContext.cs | 99 +++++++- src/bunit/TestContextBase.cs | 117 --------- .../BunitAuthorizationExtensions.cs | 2 +- .../BunitNavigationManager.cs | 8 +- .../BunitPersistentComponentState.cs | 8 +- ...Extensions.cs => TestContextExtensions.cs} | 4 +- tests/bunit.tests/TestContextBaseTest.cs | 61 ----- tests/bunit.tests/TestContextBaseTest.net5.cs | 173 ------------- tests/bunit.tests/TestContextTest.cs | 230 ++++++++++++++++++ tests/bunit.tests/TestContextTest.net6.cs | 11 - 25 files changed, 373 insertions(+), 409 deletions(-) rename src/bunit/Extensions/{TestContextBaseRenderExtensions.cs => TestContextRenderExtensions.cs} (82%) delete mode 100644 src/bunit/TestContextBase.cs rename src/bunit/TestDoubles/PersistentComponentState/{TestContextBaseExtensions.cs => TestContextExtensions.cs} (90%) delete mode 100644 tests/bunit.tests/TestContextBaseTest.cs delete mode 100644 tests/bunit.tests/TestContextBaseTest.net5.cs delete mode 100644 tests/bunit.tests/TestContextTest.net6.cs diff --git a/MIGRATION.md b/MIGRATION.md index cbafd337b..675181a74 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -39,3 +39,6 @@ The `Fake` prefix has been replaced with `Bunit` in many test doubles. For examp ### Renamed `AddTestAuthorization` to `AddAuthorization` The `AddTestAuthorization` method on `TestContext` has been renamed to `AddAuthorization`. If you used `AddTestAuthorization`, you should replace it with `AddAuthorization`. + +## Merged `TestContext` and `TestContextBase` +The `TestContext` and `TestContextBase` classes have been merged into a single `TestContext` class. All references to `TestContextBase` should replace them with `TestContext` to migrate. diff --git a/docs/samples/tests/xunit/CustomServiceProviderFactoryUsage.cs b/docs/samples/tests/xunit/CustomServiceProviderFactoryUsage.cs index df4e5800d..cee28d37a 100644 --- a/docs/samples/tests/xunit/CustomServiceProviderFactoryUsage.cs +++ b/docs/samples/tests/xunit/CustomServiceProviderFactoryUsage.cs @@ -49,10 +49,10 @@ void ConfigureContainer(ContainerBuilder containerBuilder) //get a service which was installed in the bUnit ServiceCollection - var testContextBase = Services.GetService(); + var testContext = Services.GetService(); - Assert.NotNull(testContextBase); - Assert.Equal(this, testContextBase); + Assert.NotNull(testContext); + Assert.Equal(this, testContext); } [Fact] @@ -81,9 +81,9 @@ ILifetimeScope ConfigureContainer(IServiceCollection services) //get a service which was installed in the bUnit ServiceCollection - var testContextBase = Services.GetService(); + var testContext = Services.GetService(); - Assert.NotNull(testContextBase); - Assert.Equal(this, testContextBase); + Assert.NotNull(testContext); + Assert.Equal(this, testContext); } } diff --git a/docs/site/docs/interaction/dispose-components.md b/docs/site/docs/interaction/dispose-components.md index 8995d9e94..b996b67a7 100644 --- a/docs/site/docs/interaction/dispose-components.md +++ b/docs/site/docs/interaction/dispose-components.md @@ -4,7 +4,7 @@ title: Disposing components and their children --- # Disposing components -To dispose all components rendered with a `TestContext`, use the [`DisposeComponents`](xref:Bunit.TestContextBase.DisposeComponents) method. Calling this method will dispose all rendered components, calling any `IDisposable.Dispose` or/and `IAsyncDisposable.DisposeAsync` methods they might have, and remove the components from the render tree, starting with the root components and then walking down the render tree to all the child components. +To dispose all components rendered with a `TestContext`, use the [`DisposeComponents`](xref:Bunit.TestContext.DisposeComponents) method. Calling this method will dispose all rendered components, calling any `IDisposable.Dispose` or/and `IAsyncDisposable.DisposeAsync` methods they might have, and remove the components from the render tree, starting with the root components and then walking down the render tree to all the child components. Disposing rendered components enables testing of logic in `Dispose` methods, e.g., event handlers, that should be detached to avoid memory leaks. @@ -16,7 +16,7 @@ The following example of this: > For `IAsyncDisposable` (since .net5) relying on [`WaitForState()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForState(Bunit.IRenderedFragment,Func{System.Boolean},System.Nullable{TimeSpan})) or [`WaitForAssertion()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForAssertion(Bunit.IRenderedFragment,Action,System.Nullable{TimeSpan})) will not work as a disposed component will not trigger a new render cycle. ## Checking for exceptions -`Dispose` as well as `DisposeAsync` can throw exceptions which can be asserted as well. If a component under test throws an exception in `Dispose` the [`DisposeComponents`](xref:Bunit.TestContextBase.DisposeComponents) will throw the exception to the user code: +`Dispose` as well as `DisposeAsync` can throw exceptions which can be asserted as well. If a component under test throws an exception in `Dispose` the [`DisposeComponents`](xref:Bunit.TestContext.DisposeComponents) will throw the exception to the user code: [!code-csharp[](../../../samples/tests/xunit/DisposeComponentsTest.cs#L28-L32)] diff --git a/docs/site/docs/providing-input/root-render-tree.md b/docs/site/docs/providing-input/root-render-tree.md index 898ec414e..cbc652f2d 100644 --- a/docs/site/docs/providing-input/root-render-tree.md +++ b/docs/site/docs/providing-input/root-render-tree.md @@ -7,7 +7,7 @@ title: Controlling the root render tree The root render tree, the render tree in which components under test are rendered, can be added to before components are rendered with bUnit's test context. This is mostly useful when a component under test, or a component it depends on, must be rendered inside another component, that provides a cascading value to it. -For example, when using Blazor’s authentication, it is common to add the `CascadingAuthenticationState` component higher up the render tree, such that it can provide authentication state to those components below it that need it. Adding this through the property on the type makes it possible to add it once in a shared setup method, and not have to do so in every test method during the call to [`RenderComponent()`](xref:Bunit.Rendering.RootRenderTree.Add``1(System.Action{Bunit.ComponentParameterCollectionBuilder{``0}})). +For example, when using Blazor’s authentication, it is common to add the `CascadingAuthenticationState` component higher up the render tree, such that it can provide authentication state to those components below it that need it. Adding this through the property on the type makes it possible to add it once in a shared setup method, and not have to do so in every test method during the call to [`RenderComponent()`](xref:Bunit.Rendering.RootRenderTree.Add``1(System.Action{Bunit.ComponentParameterCollectionBuilder{``0}})). This can also be useful when writing tests that use a third-party component library, that require a special root component to be added to the render tree, but which otherwise don’t change between tests. diff --git a/docs/site/docs/test-doubles/auth.md b/docs/site/docs/test-doubles/auth.md index 8a94cb728..3decf8909 100644 --- a/docs/site/docs/test-doubles/auth.md +++ b/docs/site/docs/test-doubles/auth.md @@ -15,10 +15,10 @@ The test implementation of Blazor's authentication and authorization can be put - **Authenticated** and **authorized** - **Authenticated** and **authorized** with one or more **roles**, **claims**, and/or **policies** -bUnit's authentication and authorization implementation is easily available by calling [`AddAuthorization()`](xref:Bunit.TestDoubles.BunitAuthorizationExtensions.AddAuthorization(Bunit.TestContextBase)) on a test context. This adds the necessary services to the `Services` collection and the `CascadingAuthenticationState` component to the [root render tree](xref:root-render-tree). The method returns an instance of the type that allows you to control the authentication and authorization state for a test. +bUnit's authentication and authorization implementation is easily available by calling [`AddAuthorization()`](xref:Bunit.TestDoubles.BunitAuthorizationExtensions.AddAuthorization(Bunit.TestContext)) on a test context. This adds the necessary services to the `Services` collection and the `CascadingAuthenticationState` component to the [root render tree](xref:root-render-tree). The method returns an instance of the type that allows you to control the authentication and authorization state for a test. > [!NOTE] -> If your test class inherits directly from bUnit's then you need to call the [`AddAuthorization()`](xref:Bunit.TestDoubles.BunitAuthorizationExtensions.AddAuthorization(Bunit.TestContextBase)) method on `this`, since `AddAuthorization()` is an extension method, otherwise it wont be available. E.g.: `this.AddAuthorization()`. +> If your test class inherits directly from bUnit's then you need to call the [`AddAuthorization()`](xref:Bunit.TestDoubles.BunitAuthorizationExtensions.AddAuthorization(Bunit.TestContext)) method on `this`, since `AddAuthorization()` is an extension method, otherwise it wont be available. E.g.: `this.AddAuthorization()`. The following sections show how to set each of these states in a test. diff --git a/src/bunit/ComponentFactories/InstanceComponentFactory{TComponent}.cs b/src/bunit/ComponentFactories/InstanceComponentFactory{TComponent}.cs index 0ce047387..3e3ebe461 100644 --- a/src/bunit/ComponentFactories/InstanceComponentFactory{TComponent}.cs +++ b/src/bunit/ComponentFactories/InstanceComponentFactory{TComponent}.cs @@ -18,7 +18,7 @@ public IComponent Create(Type componentType) { throw new InvalidOperationException( $"The instance object passed to the" + - $"{nameof(TestContextBase.ComponentFactories)}.{nameof(ComponentFactoryCollectionExtensions.Add)}<{typeof(TComponent).Name}>(instance) method can only be used to replace " + + $"{nameof(TestContext.ComponentFactories)}.{nameof(ComponentFactoryCollectionExtensions.Add)}<{typeof(TComponent).Name}>(instance) method can only be used to replace " + $"one {typeof(TComponent)} component in the render tree."); } diff --git a/src/bunit/Extensions/Internal/AngleSharpExtensions.cs b/src/bunit/Extensions/Internal/AngleSharpExtensions.cs index e8497a09b..a98d1830a 100644 --- a/src/bunit/Extensions/Internal/AngleSharpExtensions.cs +++ b/src/bunit/Extensions/Internal/AngleSharpExtensions.cs @@ -65,9 +65,9 @@ public static HtmlComparer GetHtmlComparer(this INodeList nodes) /// owning context, if one is available. /// /// The or null if not found. - public static TestContextBase? GetTestContext(this INode? node) + public static TestContext? GetTestContext(this INode? node) { - return node?.Owner?.Context.GetService(); + return node?.Owner?.Context.GetService(); } /// @@ -75,7 +75,7 @@ public static HtmlComparer GetHtmlComparer(this INodeList nodes) /// owning context, if one is available. /// /// The or null if not found. - public static TestContextBase? GetTestContext(this INodeList nodes) + public static TestContext? GetTestContext(this INodeList nodes) { return nodes?.Length > 0 ? nodes[0].GetTestContext() : null; } diff --git a/src/bunit/Extensions/RenderedComponentRenderExtensions.cs b/src/bunit/Extensions/RenderedComponentRenderExtensions.cs index a210d137f..a25be08e3 100644 --- a/src/bunit/Extensions/RenderedComponentRenderExtensions.cs +++ b/src/bunit/Extensions/RenderedComponentRenderExtensions.cs @@ -28,7 +28,7 @@ public static void SetParametersAndRender(this IRenderedComponent().Renderer; + var renderer = (TestRenderer)renderedComponent.Services.GetRequiredService().Renderer; try { diff --git a/src/bunit/Extensions/RenderedFragmentExtensions.cs b/src/bunit/Extensions/RenderedFragmentExtensions.cs index 236b90bb2..83732d052 100644 --- a/src/bunit/Extensions/RenderedFragmentExtensions.cs +++ b/src/bunit/Extensions/RenderedFragmentExtensions.cs @@ -55,7 +55,7 @@ public static IRenderedComponent FindComponent(this IRen { ArgumentNullException.ThrowIfNull(renderedFragment); - var renderer = renderedFragment.Services.GetRequiredService().Renderer; + var renderer = renderedFragment.Services.GetRequiredService().Renderer; return renderer.FindComponent(renderedFragment); } @@ -70,7 +70,7 @@ public static IReadOnlyList> FindComponents().Renderer; + var renderer = renderedFragment.Services.GetRequiredService().Renderer; var components = renderer.FindComponents(renderedFragment); return components.OfType>().ToArray(); diff --git a/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs b/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs index c95505202..974a99dd4 100644 --- a/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs +++ b/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs @@ -19,7 +19,7 @@ public static Task InvokeAsync(this IRenderedFragment renderedFragment, Action w return renderedFragment .Services - .GetRequiredService() + .GetRequiredService() .Renderer .Dispatcher .InvokeAsync(workItem); @@ -37,7 +37,7 @@ public static Task InvokeAsync(this IRenderedFragment renderedFragment, Func() + .GetRequiredService() .Renderer .Dispatcher .InvokeAsync(workItem); @@ -55,7 +55,7 @@ public static Task InvokeAsync(this IRenderedFragment renderedFragment, Fu return renderedFragment .Services - .GetRequiredService() + .GetRequiredService() .Renderer .Dispatcher .InvokeAsync(workItem); @@ -73,7 +73,7 @@ public static Task InvokeAsync(this IRenderedFragment renderedFragment, Fu return renderedFragment .Services - .GetRequiredService() + .GetRequiredService() .Renderer .Dispatcher .InvokeAsync(workItem); diff --git a/src/bunit/Extensions/TestContextBaseRenderExtensions.cs b/src/bunit/Extensions/TestContextRenderExtensions.cs similarity index 82% rename from src/bunit/Extensions/TestContextBaseRenderExtensions.cs rename to src/bunit/Extensions/TestContextRenderExtensions.cs index 88126a3c2..cd11843fa 100644 --- a/src/bunit/Extensions/TestContextBaseRenderExtensions.cs +++ b/src/bunit/Extensions/TestContextRenderExtensions.cs @@ -3,18 +3,18 @@ namespace Bunit.Extensions; /// -/// Extensions methods for types. +/// Extensions methods for types. /// -public static class TestContextBaseRenderExtensions +public static class TestContextRenderExtensions { /// - /// Renders a component, declared in the , inside the . + /// Renders a component, declared in the , inside the . /// /// The type of component to render. /// Test context to use to render with. /// The that contains a declaration of the component. /// A . - public static IRenderedComponent RenderInsideRenderTree(this TestContextBase testContext, RenderFragment renderFragment) + public static IRenderedComponent RenderInsideRenderTree(this TestContext testContext, RenderFragment renderFragment) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(testContext); @@ -24,12 +24,12 @@ public static IRenderedComponent RenderInsideRenderTree( } /// - /// Renders a fragment, declared in the , inside the . + /// Renders a fragment, declared in the , inside the . /// /// Test context to use to render with. /// The to render. /// A . - public static IRenderedFragment RenderInsideRenderTree(this TestContextBase testContext, RenderFragment renderFragment) + public static IRenderedFragment RenderInsideRenderTree(this TestContext testContext, RenderFragment renderFragment) { ArgumentNullException.ThrowIfNull(testContext); diff --git a/src/bunit/Extensions/TestServiceProviderExtensions.cs b/src/bunit/Extensions/TestServiceProviderExtensions.cs index 2041a48ff..ce42faeff 100644 --- a/src/bunit/Extensions/TestServiceProviderExtensions.cs +++ b/src/bunit/Extensions/TestServiceProviderExtensions.cs @@ -17,7 +17,7 @@ public static class TestServiceProviderExtensions /// /// Registers the default services required by the web . /// - public static IServiceCollection AddDefaultTestContextServices(this IServiceCollection services, TestContextBase testContext, BunitJSInterop jsInterop) + public static IServiceCollection AddDefaultTestContextServices(this IServiceCollection services, TestContext testContext, BunitJSInterop jsInterop) { ArgumentNullException.ThrowIfNull(services); ArgumentNullException.ThrowIfNull(testContext); diff --git a/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs index 6e26324a6..6408dcf5b 100644 --- a/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs +++ b/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs @@ -56,7 +56,7 @@ protected WaitForHelper( logger = renderedFragment.Services.CreateLogger>(); renderer = (TestRenderer)renderedFragment .Services - .GetRequiredService() + .GetRequiredService() .Renderer; checkPassedCompletionSource = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); timer = new Timer(_ => @@ -198,6 +198,6 @@ private static TimeSpan GetRuntimeTimeout(TimeSpan? timeout) { return Debugger.IsAttached ? Timeout.InfiniteTimeSpan - : timeout ?? TestContextBase.DefaultWaitTimeout; + : timeout ?? TestContext.DefaultWaitTimeout; } } diff --git a/src/bunit/Rendering/BunitComponentActivator.cs b/src/bunit/Rendering/BunitComponentActivator.cs index 400d94877..426b4da24 100644 --- a/src/bunit/Rendering/BunitComponentActivator.cs +++ b/src/bunit/Rendering/BunitComponentActivator.cs @@ -19,7 +19,7 @@ public IComponent CreateInstance([DynamicallyAccessedMembers(DynamicallyAccessed } // The FragmentContainer is a bUnit component added to the - // render tree to separate the components from the TestContextBase.RenderTree + // render tree to separate the components from the TestContext.RenderTree // and the components in the render fragment being rendered. // It should never be replaced by another component, as // this would break bUnits ability to detect the start diff --git a/src/bunit/Rendering/BunitHtmlParser.cs b/src/bunit/Rendering/BunitHtmlParser.cs index 0551f71c8..c44abab7f 100644 --- a/src/bunit/Rendering/BunitHtmlParser.cs +++ b/src/bunit/Rendering/BunitHtmlParser.cs @@ -34,7 +34,7 @@ public BunitHtmlParser() /// Initializes a new instance of the class /// with a AngleSharp context registered. ///
- public BunitHtmlParser(HtmlComparer htmlComparer, TestContextBase testContext) + public BunitHtmlParser(HtmlComparer htmlComparer, TestContext testContext) : this(Configuration.Default.WithCss() .With(htmlComparer ?? throw new ArgumentNullException(nameof(htmlComparer))) .With(testContext ?? throw new ArgumentNullException(nameof(testContext))) diff --git a/src/bunit/TestContext.cs b/src/bunit/TestContext.cs index afcb45ff9..de3286aa6 100644 --- a/src/bunit/TestContext.cs +++ b/src/bunit/TestContext.cs @@ -7,22 +7,116 @@ namespace Bunit; /// /// A test context is a factory that makes it possible to create components under tests. /// -public class TestContext : TestContextBase +public class TestContext : IDisposable { + private bool disposed; + private ITestRenderer? testRenderer; + + /// + /// Gets or sets the default wait timeout used by "WaitFor" operations, i.e. . + /// + /// The default is 1 second. + public static TimeSpan DefaultWaitTimeout { get; set; } = TimeSpan.FromSeconds(1); + + /// + /// Gets the renderer used by the test context. + /// + public ITestRenderer Renderer => testRenderer ??= CreateTestRenderer(); + /// /// Gets bUnits JSInterop, that allows setting up handlers for invocations /// that components under tests will issue during testing. It also makes it possible to verify that the invocations has happened as expected. /// public BunitJSInterop JSInterop { get; } = new BunitJSInterop(); + /// + /// Gets the service collection and service provider that is used when a + /// component is rendered by the test context. + /// + public TestServiceProvider Services { get; } + + /// + /// Gets the that all components rendered with the + /// RenderComponent<TComponent>() methods, are rendered inside. + /// + /// + /// Use this to add default layout- or root-components which a component under test + /// should be rendered under. + /// + public RootRenderTree RenderTree { get; } = new(); + + /// + /// Gets the . Factories added to it + /// will be used to create components during testing, starting with the last added + /// factory. If no factories in the collection can create a requested component, + /// then the default Blazor factory is used. + /// + public ComponentFactoryCollection ComponentFactories { get; } = new(); + /// /// Initializes a new instance of the class. /// public TestContext() { + Services = new TestServiceProvider(); + Services.AddSingleton(_ => ComponentFactories); Services.AddDefaultTestContextServices(this, JSInterop); } + /// + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + /// + /// Disposes of the test context resources, in particular it disposes the + /// service provider. Any async services registered with the service provider will disposed first, + /// but their disposal will not be awaited.. + /// + /// + /// The disposing parameter should be false when called from a finalizer, and true when called from the + /// method. In other words, it is true when deterministically called and false when non-deterministically called. + /// + /// Set to true if called from , false if called from a finalizer.f. + [SuppressMessage("Reliability", "CA2012:Use ValueTasks correctly", Justification = "Explicitly ignoring DisposeAsync to avoid breaking changes to API surface.")] + protected virtual void Dispose(bool disposing) + { + if (disposed || !disposing) + return; + + disposed = true; + + // Ensure the renderer is disposed before all others, + // otherwise a render cycle may be ongoing and try to access + // the service provider to perform operations. + if (testRenderer is IDisposable renderer) + { + renderer.Dispose(); + } + + // Ignore the async task as GetAwaiter().GetResult() can cause deadlock + // and implementing IAsyncDisposable in TestContext will be a breaking change. + // + // NOTE: This has to be called before Services.Dispose(). + // If there are IAsyncDisposable services registered, calling Dispose first + // causes the service provider to throw an exception. + _ = Services.DisposeAsync(); + + // The service provider should dispose of any + // disposable object it has created, when it is disposed. + Services.Dispose(); + } + + /// + /// Disposes all components rendered via this . + /// + public void DisposeComponents() + { + Renderer.DisposeComponents(); + } + /// /// Instantiates and performs a first render of a component of type . /// @@ -81,8 +175,7 @@ public virtual IRenderedFragment Render(RenderFragment renderFragment) /// protected virtual void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } - /// - protected override ITestRenderer CreateTestRenderer() + private TestRenderer CreateTestRenderer() { var renderedComponentActivator = Services.GetRequiredService(); var logger = Services.GetRequiredService(); diff --git a/src/bunit/TestContextBase.cs b/src/bunit/TestContextBase.cs deleted file mode 100644 index 95e999590..000000000 --- a/src/bunit/TestContextBase.cs +++ /dev/null @@ -1,117 +0,0 @@ -using Bunit.Rendering; - -namespace Bunit; - -/// -/// A test context is a factory that makes it possible to create components under tests. -/// -public abstract class TestContextBase : IDisposable -{ - private bool disposed; - private ITestRenderer? testRenderer; - - /// - /// Gets or sets the default wait timeout used by "WaitFor" operations, i.e. . - /// - /// The default is 1 second. - public static TimeSpan DefaultWaitTimeout { get; set; } = TimeSpan.FromSeconds(1); - - /// - /// Gets the renderer used by the test context. - /// - public ITestRenderer Renderer => testRenderer ??= CreateTestRenderer(); - - /// - /// Creates the renderer. - /// - protected abstract ITestRenderer CreateTestRenderer(); - - /// - /// Gets the service collection and service provider that is used when a - /// component is rendered by the test context. - /// - public TestServiceProvider Services { get; } - - /// - /// Gets the that all components rendered with the - /// RenderComponent<TComponent>() methods, are rendered inside. - /// - /// - /// Use this to add default layout- or root-components which a component under test - /// should be rendered under. - /// - public RootRenderTree RenderTree { get; } = new(); - - /// - /// Gets the . Factories added to it - /// will be used to create components during testing, starting with the last added - /// factory. If no factories in the collection can create a requested component, - /// then the default Blazor factory is used. - /// - public ComponentFactoryCollection ComponentFactories { get; } = new(); - - /// - /// Initializes a new instance of the class. - /// - protected TestContextBase() - { - Services = new TestServiceProvider(); - Services.AddSingleton(_ => ComponentFactories); - } - - /// - public void Dispose() - { - Dispose(disposing: true); - GC.SuppressFinalize(this); - } - - /// - /// Disposes of the test context resources, in particular it disposes the - /// service provider. Any async services registered with the service provider will disposed first, - /// but their disposal will not be awaited.. - /// - /// - /// The disposing parameter should be false when called from a finalizer, and true when called from the - /// method. In other words, it is true when deterministically called and false when non-deterministically called. - /// - /// Set to true if called from , false if called from a finalizer.f. - [SuppressMessage("Reliability", "CA2012:Use ValueTasks correctly", Justification = "Explicitly ignoring DisposeAsync to avoid breaking changes to API surface.")] - protected virtual void Dispose(bool disposing) - { - if (disposed || !disposing) - return; - - disposed = true; - - // Ensure the renderer is disposed before all others, - // otherwise a render cycle may be ongoing and try to access - // the service provider to perform operations. - if (testRenderer is IDisposable renderer) - { - renderer.Dispose(); - } - - // Ignore the async task as GetAwaiter().GetResult() can cause deadlock - // and implementing IAsyncDisposable in TestContext will be a breaking change. - // - // NOTE: This has to be called before Services.Dispose(). - // If there are IAsyncDisposable services registered, calling Dispose first - // causes the service provider to throw an exception. - _ = Services.DisposeAsync(); - - // The service provider should dispose of any - // disposable object it has created, when it is disposed. -#pragma warning disable S3966 // On purpose to dispose synchronously and asynchronously - Services.Dispose(); -#pragma warning restore S3966 - } - - /// - /// Disposes all components rendered via this . - /// - public void DisposeComponents() - { - Renderer.DisposeComponents(); - } -} diff --git a/src/bunit/TestDoubles/Authorization/BunitAuthorizationExtensions.cs b/src/bunit/TestDoubles/Authorization/BunitAuthorizationExtensions.cs index 82545ed28..dbd62c071 100644 --- a/src/bunit/TestDoubles/Authorization/BunitAuthorizationExtensions.cs +++ b/src/bunit/TestDoubles/Authorization/BunitAuthorizationExtensions.cs @@ -14,7 +14,7 @@ public static class BunitAuthorizationExtensions /// an authenticated user, as well as adding the component to the /// test contexts render tree. /// - public static TestAuthorizationContext AddAuthorization(this TestContextBase context) + public static TestAuthorizationContext AddAuthorization(this TestContext context) { ArgumentNullException.ThrowIfNull(context); diff --git a/src/bunit/TestDoubles/NavigationManager/BunitNavigationManager.cs b/src/bunit/TestDoubles/NavigationManager/BunitNavigationManager.cs index d4e19e2de..171c51f62 100644 --- a/src/bunit/TestDoubles/NavigationManager/BunitNavigationManager.cs +++ b/src/bunit/TestDoubles/NavigationManager/BunitNavigationManager.cs @@ -12,7 +12,7 @@ namespace Bunit.TestDoubles; [DebuggerDisplay("Current Uri: {Uri}, History Count: {History.Count}")] public sealed class BunitNavigationManager : NavigationManager { - private readonly TestContextBase testContextBase; + private readonly TestContext testContext; private readonly Stack history = new(); /// @@ -28,9 +28,9 @@ public sealed class BunitNavigationManager : NavigationManager /// Initializes a new instance of the class. /// [SuppressMessage("Minor Code Smell", "S1075:URIs should not be hardcoded", Justification = "By design. Bunit navigation manager defaults to local host as base URI.")] - public BunitNavigationManager(TestContextBase testContextBase) + public BunitNavigationManager(TestContext testContext) { - this.testContextBase = testContextBase; + this.testContext = testContext; Initialize("http://localhost/", "http://localhost/"); } @@ -51,7 +51,7 @@ protected override void NavigateToCore(string uri, NavigationOptions options) history.Pop(); HistoryEntryState = options.ForceLoad ? null : options.HistoryEntryState; - testContextBase.Renderer.Dispatcher.InvokeAsync(async () => + testContext.Renderer.Dispatcher.InvokeAsync(async () => { Uri = absoluteUri.OriginalString; diff --git a/src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentState.cs b/src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentState.cs index c96b29ca6..d6ae10f98 100644 --- a/src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentState.cs +++ b/src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentState.cs @@ -27,7 +27,7 @@ internal BunitPersistentComponentState(IServiceProvider services) { store = new BunitPersistentComponentStateStore(); manager = new Lazy(() => services.GetRequiredService()); - renderer = new Lazy(() => services.GetRequiredService().Renderer); + renderer = new Lazy(() => services.GetRequiredService().Renderer); } /// @@ -36,7 +36,7 @@ internal BunitPersistentComponentState(IServiceProvider services) /// component persistence. /// /// - /// Only call this method after all services has been registered with the . + /// Only call this method after all services has been registered with the . /// Calling this method will lookup dependencies of the /// from the , which means no other services can be registered after this point. /// @@ -50,7 +50,7 @@ public void TriggerOnPersisting() /// Persists under the given in the store. /// /// - /// Only call this method after all services has been registered with the . + /// Only call this method after all services has been registered with the . /// Calling this method will lookup dependencies of the /// from the , which means no other services can be registered after this point. /// @@ -70,7 +70,7 @@ public void Persist(string key, TValue instance) /// When the key is present, the state is successfully returned via . /// /// - /// Only call this method after all services has been registered with the . + /// Only call this method after all services has been registered with the . /// Calling this method will lookup dependencies of the /// from the , which means no other services can be registered after this point. /// diff --git a/src/bunit/TestDoubles/PersistentComponentState/TestContextBaseExtensions.cs b/src/bunit/TestDoubles/PersistentComponentState/TestContextExtensions.cs similarity index 90% rename from src/bunit/TestDoubles/PersistentComponentState/TestContextBaseExtensions.cs rename to src/bunit/TestDoubles/PersistentComponentState/TestContextExtensions.cs index adaa05034..f0d3b655c 100644 --- a/src/bunit/TestDoubles/PersistentComponentState/TestContextBaseExtensions.cs +++ b/src/bunit/TestDoubles/PersistentComponentState/TestContextExtensions.cs @@ -5,14 +5,14 @@ namespace Bunit.TestDoubles; /// /// Extensions related to . /// -public static class TestContextBaseExtensions +public static class TestContextExtensions { /// /// Adds and returns a to the services of the . /// /// The test context to add the to. /// The added . - public static BunitPersistentComponentState AddBunitPersistentComponentState(this TestContextBase testContext) + public static BunitPersistentComponentState AddBunitPersistentComponentState(this TestContext testContext) { ArgumentNullException.ThrowIfNull(testContext); diff --git a/tests/bunit.tests/TestContextBaseTest.cs b/tests/bunit.tests/TestContextBaseTest.cs deleted file mode 100644 index e82ddbec8..000000000 --- a/tests/bunit.tests/TestContextBaseTest.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Bunit.TestAssets.SampleComponents.DisposeComponents; - -namespace Bunit; - -public partial class TestContextBaseTest : TestContext -{ - [Fact(DisplayName = "DisposeComponents disposes rendered components in parent to child order")] - public void Test101() - { - var callStack = new List(); - RenderComponent(ps => ps.Add(p => p.CallStack, callStack)); - - DisposeComponents(); - - callStack.Count.ShouldBe(2); - callStack[0].ShouldBe("ParentDispose"); - callStack[1].ShouldBe("ChildDispose"); - } - - [Fact(DisplayName = "DisposeComponents disposes multiple rendered components")] - public void Test102() - { - var callStack = new List(); - RenderComponent(ps => ps.Add(p => p.CallStack, callStack)); - RenderComponent(ps => ps.Add(p => p.CallStack, callStack)); - - DisposeComponents(); - - callStack.Count.ShouldBe(2); - } - - [Fact(DisplayName = "DisposeComponents rethrows exceptions from Dispose methods in components")] - public void Test103() - { - RenderComponent(); - var action = () => DisposeComponents(); - - action.ShouldThrow(); - } - - [Fact(DisplayName = "DisposeComponents disposes components nested in render fragments")] - public void Test104() - { - var callStack = new List(); - Render(DisposeFragments.ChildDisposeAsFragment(callStack)); - - DisposeComponents(); - - callStack.Count.ShouldBe(1); - } - - private sealed class ThrowExceptionComponent : ComponentBase, IDisposable - { - public void Dispose() - { -#pragma warning disable S3877 - throw new NotSupportedException(); -#pragma warning restore S3877 - } - } -} diff --git a/tests/bunit.tests/TestContextBaseTest.net5.cs b/tests/bunit.tests/TestContextBaseTest.net5.cs deleted file mode 100644 index 09af8e57a..000000000 --- a/tests/bunit.tests/TestContextBaseTest.net5.cs +++ /dev/null @@ -1,173 +0,0 @@ -using Bunit.TestAssets.SampleComponents.DisposeComponents; - -namespace Bunit; - -public partial class TestContextBaseTest : TestContext -{ - [Fact(DisplayName = "ComponentFactories CanCreate() method are checked during component instantiation")] - public void Test0001() - { - var mock = CreateMockComponentFactory(canCreate: _ => false, create: _ => null); - ComponentFactories.Add(mock); - - RenderComponent(); - - mock.Received(1).CanCreate(typeof(Simple1)); - mock.DidNotReceive().Create(Arg.Any()); - } - - [Fact(DisplayName = "ComponentFactories Create() method is called when their CanCreate() method returns true")] - public void Test0002() - { - var mock = CreateMockComponentFactory(canCreate: _ => true, create: _ => new Simple1()); - ComponentFactories.Add(mock); - - RenderComponent(); - - mock.Received(1).CanCreate(typeof(Simple1)); - mock.Received(1).Create(typeof(Simple1)); - } - - [Fact(DisplayName = "ComponentFactories is used in last added order")] - public void Test0003() - { - var firstMock = CreateMockComponentFactory(canCreate: _ => true, create: _ => new Simple1()); - var secondMock = CreateMockComponentFactory(canCreate: _ => true, create: _ => new Simple1()); - ComponentFactories.Add(firstMock); - ComponentFactories.Add(secondMock); - - RenderComponent(); - - firstMock.DidNotReceive().CanCreate(Arg.Any()); - firstMock.DidNotReceive().Create(Arg.Any()); - secondMock.Received(1).CanCreate(typeof(Simple1)); - secondMock.Received(1).Create(typeof(Simple1)); - } - - [Fact(DisplayName = "DisposeComponents captures exceptions from DisposeAsync in Renderer.UnhandledException")] - public async Task Test201() - { - var tcs = new TaskCompletionSource(); - var expected = new NotSupportedException(); - RenderComponent( - ps => ps.Add(p => p.DisposedTask, tcs.Task)); - - DisposeComponents(); - - tcs.SetException(expected); - var actual = await Renderer.UnhandledException; - actual.ShouldBeSameAs(expected); - } - - [Fact(DisplayName = "DisposeComponents calls DisposeAsync on rendered components")] - public async Task Test202() - { - var cut = RenderComponent(); - var wasDisposedTask = cut.Instance.DisposedTask; - - DisposeComponents(); - - await wasDisposedTask.ShouldCompleteWithin(TimeSpan.FromSeconds(1)); - } - - [Fact(DisplayName = "DisposeComponents should dispose components added via ComponentFactory")] - public void Test203() - { - ComponentFactories.Add(); - var cut = RenderComponent(ps => ps.Add(p => p.CallStack, new List())); - var instance = cut.FindComponent().Instance; - - DisposeComponents(); - - instance.WasDisposed.ShouldBeTrue(); - } - - [Fact(DisplayName = "Can correctly resolve and dispose of scoped disposable service")] - public void Net5Test001() - { - AsyncDisposableService asyncDisposable; - using (var sut = new TestContext()) - { - sut.Services.AddScoped(); - asyncDisposable = sut.Services.GetService(); - } - asyncDisposable.IsDisposed.ShouldBeTrue(); - } - - [Fact(DisplayName = "Can correctly resolve and dispose of transient disposable service")] - public void Net5Test002() - { - AsyncDisposableService asyncDisposable; - using (var sut = new TestContext()) - { - sut.Services.AddTransient(); - asyncDisposable = sut.Services.GetService(); - } - asyncDisposable.IsDisposed.ShouldBeTrue(); - } - - [Fact(DisplayName = "Can correctly resolve and dispose of singleton disposable service")] - public void Net5Test003() - { - AsyncDisposableService asyncDisposable; - using (var sut = new TestContext()) - { - sut.Services.AddSingleton(); - asyncDisposable = sut.Services.GetService(); - } - asyncDisposable.IsDisposed.ShouldBeTrue(); - } - - private sealed class AsyncDisposableService : IAsyncDisposable - { - public bool IsDisposed { get; private set; } - - public ValueTask DisposeAsync() - { - IsDisposed = true; - return ValueTask.CompletedTask; - } - } - - private sealed class MyChildDisposeStub : ComponentBase, IDisposable - { - public bool WasDisposed { get; private set; } - - public void Dispose() - { - WasDisposed = true; - } - } - - private sealed class AsyncThrowExceptionComponent : ComponentBase, IAsyncDisposable - { - [Parameter] - public Task DisposedTask { get; set; } - - public async ValueTask DisposeAsync() - { - await DisposedTask; - } - } - - private sealed class AsyncDisposableComponent : ComponentBase, IAsyncDisposable - { - private readonly TaskCompletionSource tsc = new(); - - public Task DisposedTask => tsc.Task; - - public async ValueTask DisposeAsync() - { - await Task.Delay(10); - tsc.SetResult(); - } - } - - private static IComponentFactory CreateMockComponentFactory(Func canCreate, Func create) - { - var result = Substitute.For(); - result.CanCreate(Arg.Any()).Returns(call => canCreate((Type)call[0])); - result.Create(Arg.Any()).Returns(call => create((Type)call[0])); - return result; - } -} diff --git a/tests/bunit.tests/TestContextTest.cs b/tests/bunit.tests/TestContextTest.cs index faa2fefa3..86049d7b9 100644 --- a/tests/bunit.tests/TestContextTest.cs +++ b/tests/bunit.tests/TestContextTest.cs @@ -1,9 +1,55 @@ +using Bunit.TestAssets.SampleComponents.DisposeComponents; using Bunit.TestDoubles; namespace Bunit; public partial class TestContextTest : TestContext { + [Fact(DisplayName = "DisposeComponents disposes rendered components in parent to child order")] + public void Test101() + { + var callStack = new List(); + RenderComponent(ps => ps.Add(p => p.CallStack, callStack)); + + DisposeComponents(); + + callStack.Count.ShouldBe(2); + callStack[0].ShouldBe("ParentDispose"); + callStack[1].ShouldBe("ChildDispose"); + } + + [Fact(DisplayName = "DisposeComponents disposes multiple rendered components")] + public void Test102() + { + var callStack = new List(); + RenderComponent(ps => ps.Add(p => p.CallStack, callStack)); + RenderComponent(ps => ps.Add(p => p.CallStack, callStack)); + + DisposeComponents(); + + callStack.Count.ShouldBe(2); + } + + [Fact(DisplayName = "DisposeComponents rethrows exceptions from Dispose methods in components")] + public void Test103() + { + RenderComponent(); + var action = () => DisposeComponents(); + + action.ShouldThrow(); + } + + [Fact(DisplayName = "DisposeComponents disposes components nested in render fragments")] + public void Test104() + { + var callStack = new List(); + Render(DisposeFragments.ChildDisposeAsFragment(callStack)); + + DisposeComponents(); + + callStack.Count.ShouldBe(1); + } + [Fact(DisplayName = "The test service provider should register a placeholder HttpClient which throws exceptions")] public void Test024() { @@ -74,6 +120,127 @@ public void Test040() { Should.NotThrow(() => RenderComponent().Find("button").Click()); } + + [Fact(DisplayName = "TestContext should provide a default IErrorBoundaryLogger")] + public void Test001() + { + IErrorBoundaryLogger logger = Services.GetService(); + logger.ShouldNotBe(null); + } + + [Fact(DisplayName = "ComponentFactories CanCreate() method are checked during component instantiation")] + public void Test0001() + { + var mock = CreateMockComponentFactory(canCreate: _ => false, create: _ => null); + ComponentFactories.Add(mock); + + RenderComponent(); + + mock.Received(1).CanCreate(typeof(Simple1)); + mock.DidNotReceive().Create(Arg.Any()); + } + + [Fact(DisplayName = "ComponentFactories Create() method is called when their CanCreate() method returns true")] + public void Test0002() + { + var mock = CreateMockComponentFactory(canCreate: _ => true, create: _ => new Simple1()); + ComponentFactories.Add(mock); + + RenderComponent(); + + mock.Received(1).CanCreate(typeof(Simple1)); + mock.Received(1).Create(typeof(Simple1)); + } + + [Fact(DisplayName = "ComponentFactories is used in last added order")] + public void Test0003() + { + var firstMock = CreateMockComponentFactory(canCreate: _ => true, create: _ => new Simple1()); + var secondMock = CreateMockComponentFactory(canCreate: _ => true, create: _ => new Simple1()); + ComponentFactories.Add(firstMock); + ComponentFactories.Add(secondMock); + + RenderComponent(); + + firstMock.DidNotReceive().CanCreate(Arg.Any()); + firstMock.DidNotReceive().Create(Arg.Any()); + secondMock.Received(1).CanCreate(typeof(Simple1)); + secondMock.Received(1).Create(typeof(Simple1)); + } + + [Fact(DisplayName = "DisposeComponents captures exceptions from DisposeAsync in Renderer.UnhandledException")] + public async Task Test201() + { + var tcs = new TaskCompletionSource(); + var expected = new NotSupportedException(); + RenderComponent( + ps => ps.Add(p => p.DisposedTask, tcs.Task)); + + DisposeComponents(); + + tcs.SetException(expected); + var actual = await Renderer.UnhandledException; + actual.ShouldBeSameAs(expected); + } + + [Fact(DisplayName = "DisposeComponents calls DisposeAsync on rendered components")] + public async Task Test202() + { + var cut = RenderComponent(); + var wasDisposedTask = cut.Instance.DisposedTask; + + DisposeComponents(); + + await wasDisposedTask.ShouldCompleteWithin(TimeSpan.FromSeconds(1)); + } + + [Fact(DisplayName = "DisposeComponents should dispose components added via ComponentFactory")] + public void Test203() + { + ComponentFactories.Add(); + var cut = RenderComponent(ps => ps.Add(p => p.CallStack, new List())); + var instance = cut.FindComponent().Instance; + + DisposeComponents(); + + instance.WasDisposed.ShouldBeTrue(); + } + + [Fact(DisplayName = "Can correctly resolve and dispose of scoped disposable service")] + public void Net5Test001() + { + AsyncDisposableService asyncDisposable; + using (var sut = new TestContext()) + { + sut.Services.AddScoped(); + asyncDisposable = sut.Services.GetService(); + } + asyncDisposable.IsDisposed.ShouldBeTrue(); + } + + [Fact(DisplayName = "Can correctly resolve and dispose of transient disposable service")] + public void Net5Test002() + { + AsyncDisposableService asyncDisposable; + using (var sut = new TestContext()) + { + sut.Services.AddTransient(); + asyncDisposable = sut.Services.GetService(); + } + asyncDisposable.IsDisposed.ShouldBeTrue(); + } + + [Fact(DisplayName = "Can correctly resolve and dispose of singleton disposable service")] + public void Net5Test003() + { + AsyncDisposableService asyncDisposable; + using (var sut = new TestContext()) + { + sut.Services.AddSingleton(); + asyncDisposable = sut.Services.GetService(); + } + asyncDisposable.IsDisposed.ShouldBeTrue(); + } private sealed class ReceivesCascadingValue : ComponentBase { @@ -81,4 +248,67 @@ private sealed class ReceivesCascadingValue : ComponentBase [Parameter] public object? Dummy { get; set; } } + + private sealed class ThrowExceptionComponent : ComponentBase, IDisposable + { + public void Dispose() + { +#pragma warning disable S3877 + throw new NotSupportedException(); +#pragma warning restore S3877 + } + } + + private sealed class AsyncDisposableService : IAsyncDisposable + { + public bool IsDisposed { get; private set; } + + public ValueTask DisposeAsync() + { + IsDisposed = true; + return ValueTask.CompletedTask; + } + } + + private sealed class MyChildDisposeStub : ComponentBase, IDisposable + { + public bool WasDisposed { get; private set; } + + public void Dispose() + { + WasDisposed = true; + } + } + + private sealed class AsyncThrowExceptionComponent : ComponentBase, IAsyncDisposable + { + [Parameter] + public Task DisposedTask { get; set; } + + public async ValueTask DisposeAsync() + { + await DisposedTask; + } + } + + private sealed class AsyncDisposableComponent : ComponentBase, IAsyncDisposable + { + private readonly TaskCompletionSource tsc = new(); + + public Task DisposedTask => tsc.Task; + + public async ValueTask DisposeAsync() + { + await Task.Delay(10); + tsc.SetResult(); + } + } + + private static IComponentFactory CreateMockComponentFactory(Func canCreate, Func create) + { + var result = Substitute.For(); + result.CanCreate(Arg.Any()).Returns(call => canCreate((Type)call[0])); + result.Create(Arg.Any()).Returns(call => create((Type)call[0])); + return result; + } } diff --git a/tests/bunit.tests/TestContextTest.net6.cs b/tests/bunit.tests/TestContextTest.net6.cs deleted file mode 100644 index 9ba770e7c..000000000 --- a/tests/bunit.tests/TestContextTest.net6.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Bunit; - -public partial class TestContextTest : TestContext -{ - [Fact(DisplayName = "TestContext should provide a default IErrorBoundaryLogger")] - public void Test001() - { - IErrorBoundaryLogger logger = Services.GetService(); - logger.ShouldNotBe(null); - } -} From 5a89ad539b1690c8fc2b60aa4ae068b5d184c764 Mon Sep 17 00:00:00 2001 From: Steven Giesel Date: Sun, 3 Mar 2024 11:18:19 +0100 Subject: [PATCH 10/42] refactor: Remove ITestRenderer interface --- src/bunit/Diffing/HtmlComparer.cs | 2 +- .../TriggerEventDispatchExtensions.cs | 10 +-- .../RenderedComponentRenderExtensions.cs | 2 +- .../RenderedFragmentInvokeAsyncExtensions.cs | 8 +- .../Extensions/TestRendererExtensions.cs | 6 +- .../WaitForHelpers/WaitForHelper.cs | 2 +- src/bunit/IRenderedFragment.cs | 6 +- src/bunit/Rendering/ITestRenderer.cs | 81 ------------------- src/bunit/Rendering/RenderEvent.cs | 2 +- src/bunit/Rendering/TestRenderer.cs | 4 +- src/bunit/TestContext.cs | 4 +- src/bunit/TestContextWrapper.cs | 2 +- .../BunitPersistentComponentState.cs | 4 +- 13 files changed, 26 insertions(+), 107 deletions(-) delete mode 100644 src/bunit/Rendering/ITestRenderer.cs diff --git a/src/bunit/Diffing/HtmlComparer.cs b/src/bunit/Diffing/HtmlComparer.cs index b88027e23..2dd73d112 100644 --- a/src/bunit/Diffing/HtmlComparer.cs +++ b/src/bunit/Diffing/HtmlComparer.cs @@ -8,7 +8,7 @@ namespace Bunit.Diffing; /// -/// Represents a test HTML comparer, that is configured to work with markup generated by the and classes. +/// Represents a test HTML comparer, that is configured to work with markup generated by the and classes. /// public sealed class HtmlComparer { diff --git a/src/bunit/EventDispatchExtensions/TriggerEventDispatchExtensions.cs b/src/bunit/EventDispatchExtensions/TriggerEventDispatchExtensions.cs index 2a243b8b1..62e44e9a1 100644 --- a/src/bunit/EventDispatchExtensions/TriggerEventDispatchExtensions.cs +++ b/src/bunit/EventDispatchExtensions/TriggerEventDispatchExtensions.cs @@ -63,7 +63,7 @@ public static Task TriggerEventAsync(this IElement element, string eventName, Ev ArgumentNullException.ThrowIfNull(eventName); var renderer = element.GetTestContext()?.Renderer - ?? throw new InvalidOperationException($"Blazor events can only be raised on elements rendered with the Blazor test renderer '{nameof(ITestRenderer)}'."); + ?? throw new InvalidOperationException($"Blazor events can only be raised on elements rendered with the Blazor test renderer '{nameof(TestRenderer)}'."); // TriggerEventsAsync will traverse the DOM tree to find // all event handlers that needs to be triggered. This is done @@ -78,7 +78,7 @@ public static Task TriggerEventAsync(this IElement element, string eventName, Ev } [SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "HTML events are standardize to lower case and safe in this context.")] - private static Task TriggerEventsAsync(ITestRenderer renderer, IElement element, string eventName, EventArgs eventArgs) + private static Task TriggerEventsAsync(TestRenderer renderer, IElement element, string eventName, EventArgs eventArgs) { var isNonBubblingEvent = NonBubblingEvents.Contains(eventName.ToLowerInvariant()); var unwrappedElement = element.Unwrap(); @@ -88,7 +88,7 @@ private static Task TriggerEventsAsync(ITestRenderer renderer, IElement element, : TriggerBubblingEventAsync(renderer, unwrappedElement, eventName, eventArgs); } - private static Task TriggerNonBubblingEventAsync(ITestRenderer renderer, IElement element, string eventName, EventArgs eventArgs) + private static Task TriggerNonBubblingEventAsync(TestRenderer renderer, IElement element, string eventName, EventArgs eventArgs) { var eventAttrName = Htmlizer.ToBlazorAttribute(eventName); @@ -105,7 +105,7 @@ private static Task TriggerNonBubblingEventAsync(ITestRenderer renderer, IElemen throw new MissingEventHandlerException(element, eventName); } - private static Task TriggerBubblingEventAsync(ITestRenderer renderer, IElement element, string eventName, EventArgs eventArgs) + private static Task TriggerBubblingEventAsync(TestRenderer renderer, IElement element, string eventName, EventArgs eventArgs) { var eventTasks = GetDispatchEventTasks(renderer, element, eventName, eventArgs); @@ -118,7 +118,7 @@ private static Task TriggerBubblingEventAsync(ITestRenderer renderer, IElement e } private static List GetDispatchEventTasks( - ITestRenderer renderer, + TestRenderer renderer, IElement element, string eventName, EventArgs eventArgs) diff --git a/src/bunit/Extensions/RenderedComponentRenderExtensions.cs b/src/bunit/Extensions/RenderedComponentRenderExtensions.cs index a25be08e3..8efe2f5d2 100644 --- a/src/bunit/Extensions/RenderedComponentRenderExtensions.cs +++ b/src/bunit/Extensions/RenderedComponentRenderExtensions.cs @@ -28,7 +28,7 @@ public static void SetParametersAndRender(this IRenderedComponent().Renderer; + var renderer = renderedComponent.Services.GetRequiredService().Renderer; try { diff --git a/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs b/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs index 974a99dd4..88abb6cf2 100644 --- a/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs +++ b/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs @@ -8,7 +8,7 @@ namespace Bunit; public static class RenderedFragmentInvokeAsyncExtensions { /// - /// Invokes the given in the context of the associated . + /// Invokes the given in the context of the associated . /// /// The rendered fragment whose dispatcher to invoke with. /// The work item to execute on the renderer's thread. @@ -26,7 +26,7 @@ public static Task InvokeAsync(this IRenderedFragment renderedFragment, Action w } /// - /// Invokes the given in the context of the associated . + /// Invokes the given in the context of the associated . /// /// The rendered component whose dispatcher to invoke with. /// The work item to execute on the renderer's thread. @@ -44,7 +44,7 @@ public static Task InvokeAsync(this IRenderedFragment renderedFragment, Func - /// Invokes the given in the context of the associated . + /// Invokes the given in the context of the associated . /// /// The rendered component whose dispatcher to invoke with. /// The work item to execute on the renderer's thread. @@ -62,7 +62,7 @@ public static Task InvokeAsync(this IRenderedFragment renderedFragment, Fu } /// - /// Invokes the given in the context of the associated . + /// Invokes the given in the context of the associated . /// /// The rendered component whose dispatcher to invoke with. /// The work item to execute on the renderer's thread. diff --git a/src/bunit/Extensions/TestRendererExtensions.cs b/src/bunit/Extensions/TestRendererExtensions.cs index d1b6243a5..074028a38 100644 --- a/src/bunit/Extensions/TestRendererExtensions.cs +++ b/src/bunit/Extensions/TestRendererExtensions.cs @@ -3,7 +3,7 @@ namespace Bunit.Extensions; /// -/// Helper methods that make it easier to work directly with a +/// Helper methods that make it easier to work directly with a /// in bUnit web. /// public static class TestRendererExtensions @@ -15,7 +15,7 @@ public static class TestRendererExtensions /// The renderer to use. /// The parameters to pass to the component. /// A that provides access to the rendered component. - public static IRenderedComponent RenderComponent(this ITestRenderer renderer, params ComponentParameter[] parameters) + public static IRenderedComponent RenderComponent(this TestRenderer renderer, params ComponentParameter[] parameters) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(renderer); @@ -34,7 +34,7 @@ public static IRenderedComponent RenderComponent(this IT /// The renderer to use. /// The a builder to create parameters to pass to the component. /// A that provides access to the rendered component. - public static IRenderedComponent RenderComponent(this ITestRenderer renderer, Action> parameterBuilder) + public static IRenderedComponent RenderComponent(this TestRenderer renderer, Action> parameterBuilder) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(renderer); diff --git a/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs index 6408dcf5b..650ccccea 100644 --- a/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs +++ b/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs @@ -54,7 +54,7 @@ protected WaitForHelper( this.completeChecker = completeChecker ?? throw new ArgumentNullException(nameof(completeChecker)); logger = renderedFragment.Services.CreateLogger>(); - renderer = (TestRenderer)renderedFragment + renderer = renderedFragment .Services .GetRequiredService() .Renderer; diff --git a/src/bunit/IRenderedFragment.cs b/src/bunit/IRenderedFragment.cs index 61a1a0192..ebf887a3d 100644 --- a/src/bunit/IRenderedFragment.cs +++ b/src/bunit/IRenderedFragment.cs @@ -14,7 +14,7 @@ public interface IRenderedFragment : IDisposable int RenderCount { get; } /// - /// Gets a value indicating whether the rendered component or fragment has been disposed by the . + /// Gets a value indicating whether the rendered component or fragment has been disposed by the . /// bool IsDisposed { get; } @@ -24,7 +24,7 @@ public interface IRenderedFragment : IDisposable int ComponentId { get; } /// - /// Called by the owning when it finishes a render. + /// Called by the owning when it finishes a render. /// /// A that represents a render. void OnRender(RenderEvent renderEvent); @@ -51,6 +51,6 @@ public interface IRenderedFragment : IDisposable /// /// Gets the AngleSharp based /// on the HTML markup from the rendered fragment/component. - /// + /// INodeList Nodes { get; } } diff --git a/src/bunit/Rendering/ITestRenderer.cs b/src/bunit/Rendering/ITestRenderer.cs deleted file mode 100644 index 5e445dec0..000000000 --- a/src/bunit/Rendering/ITestRenderer.cs +++ /dev/null @@ -1,81 +0,0 @@ -namespace Bunit.Rendering; - -/// -/// Represents a generalized Blazor renderer for testing purposes. -/// -public interface ITestRenderer -{ - /// - /// Gets a , which completes when an unhandled exception - /// is thrown during the rendering of a component, that is caught by the renderer. - /// - Task UnhandledException { get; } - - /// - /// Gets the associated with this . - /// - Dispatcher Dispatcher { get; } - - /// - /// Notifies the renderer that an event has occurred. - /// - /// The value from the original event attribute. - /// Information that the renderer can use to update the state of the existing render tree to match the UI. - /// Arguments to be passed to the event handler. - /// A which will complete once all asynchronous processing related to the event has completed. - Task DispatchEventAsync( - ulong eventHandlerId, - EventFieldInfo fieldInfo, - EventArgs eventArgs); - - /// - /// Notifies the renderer that an event has occurred. - /// - /// The value from the original event attribute. - /// Information that the renderer can use to update the state of the existing render tree to match the UI. - /// Arguments to be passed to the event handler. - /// Set to true to ignore the . - /// A which will complete once all asynchronous processing related to the event has completed. - Task DispatchEventAsync( - ulong eventHandlerId, - EventFieldInfo fieldInfo, - EventArgs eventArgs, - bool ignoreUnknownEventHandlers); - - /// - /// Renders the . - /// - /// The to render. - /// A that provides access to the rendered . - IRenderedFragment RenderFragment(RenderFragment renderFragment); - - /// - /// Renders a with the passed to it. - /// - /// The type of component to render. - /// The parameters to pass to the component. - /// A that provides access to the rendered component. - IRenderedComponent RenderComponent(ComponentParameterCollection parameters) - where TComponent : IComponent; - - /// - /// Performs a depth-first search for the first child component of the . - /// - /// Type of component to find. - /// Parent component to search. - IRenderedComponent FindComponent(IRenderedFragment parentComponent) - where TComponent : IComponent; - - /// - /// Performs a depth-first search for all child components of the . - /// - /// Type of components to find. - /// Parent component to search. - IReadOnlyList> FindComponents(IRenderedFragment parentComponent) - where TComponent : IComponent; - - /// - /// Disposes all components rendered by the . - /// - void DisposeComponents(); -} diff --git a/src/bunit/Rendering/RenderEvent.cs b/src/bunit/Rendering/RenderEvent.cs index cd8561e16..9069cb786 100644 --- a/src/bunit/Rendering/RenderEvent.cs +++ b/src/bunit/Rendering/RenderEvent.cs @@ -1,7 +1,7 @@ namespace Bunit.Rendering; /// -/// Represents an render event from a . +/// Represents an render event from a . /// public sealed class RenderEvent { diff --git a/src/bunit/Rendering/TestRenderer.cs b/src/bunit/Rendering/TestRenderer.cs index 06e787d62..984d7434e 100644 --- a/src/bunit/Rendering/TestRenderer.cs +++ b/src/bunit/Rendering/TestRenderer.cs @@ -6,9 +6,9 @@ namespace Bunit.Rendering; /// -/// Represents a bUnit used to render Blazor components and fragments during bUnit tests. +/// Represents a bUnit used to render Blazor components and fragments during bUnit tests. /// -public class TestRenderer : Renderer, ITestRenderer +public sealed class TestRenderer : Renderer { [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_isBatchInProgress")] extern static ref bool GetIsBatchInProgressField(Renderer renderer); diff --git a/src/bunit/TestContext.cs b/src/bunit/TestContext.cs index de3286aa6..47d492202 100644 --- a/src/bunit/TestContext.cs +++ b/src/bunit/TestContext.cs @@ -10,7 +10,7 @@ namespace Bunit; public class TestContext : IDisposable { private bool disposed; - private ITestRenderer? testRenderer; + private TestRenderer? testRenderer; /// /// Gets or sets the default wait timeout used by "WaitFor" operations, i.e. . @@ -21,7 +21,7 @@ public class TestContext : IDisposable /// /// Gets the renderer used by the test context. /// - public ITestRenderer Renderer => testRenderer ??= CreateTestRenderer(); + public TestRenderer Renderer => testRenderer ??= CreateTestRenderer(); /// /// Gets bUnits JSInterop, that allows setting up handlers for invocations diff --git a/src/bunit/TestContextWrapper.cs b/src/bunit/TestContextWrapper.cs index a6a9c57c0..8afa6b4f8 100644 --- a/src/bunit/TestContextWrapper.cs +++ b/src/bunit/TestContextWrapper.cs @@ -17,7 +17,7 @@ public abstract class TestContextWrapper /// /// Gets the renderer used by the test context. /// - public ITestRenderer Renderer => TestContext?.Renderer ?? throw new InvalidOperationException("The TestContext has not been initialized."); + public TestRenderer Renderer => TestContext?.Renderer ?? throw new InvalidOperationException("The TestContext has not been initialized."); /// /// Gets the service collection and service provider that is used when a diff --git a/src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentState.cs b/src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentState.cs index d6ae10f98..ae8b12f58 100644 --- a/src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentState.cs +++ b/src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentState.cs @@ -17,7 +17,7 @@ public sealed class BunitPersistentComponentState }; private readonly BunitPersistentComponentStateStore store; private readonly Lazy manager; - private readonly Lazy renderer; + private readonly Lazy renderer; /// /// Initializes a new instance of the class. @@ -27,7 +27,7 @@ internal BunitPersistentComponentState(IServiceProvider services) { store = new BunitPersistentComponentStateStore(); manager = new Lazy(() => services.GetRequiredService()); - renderer = new Lazy(() => services.GetRequiredService().Renderer); + renderer = new Lazy(() => services.GetRequiredService().Renderer); } /// From 28c2ff15c015dbba93b8d8a1de4d924bed116e49 Mon Sep 17 00:00:00 2001 From: Steven Giesel Date: Sun, 3 Mar 2024 11:29:25 +0100 Subject: [PATCH 11/42] refactor: Remove abstraction around RenderedFragment/RenderedComponent --- MIGRATION.md | 6 +- .../docs/getting-started/writing-tests.md | 2 +- .../docs/interaction/awaiting-async-state.md | 4 +- .../docs/interaction/dispose-components.md | 2 +- .../interaction/trigger-event-handlers.md | 4 +- docs/site/docs/interaction/trigger-renders.md | 20 +-- .../passing-parameters-to-components.md | 4 +- .../substituting-components.md | 14 +- docs/site/docs/test-doubles/input-file.md | 4 +- .../site/docs/verification/async-assertion.md | 4 +- .../verification/verify-component-state.md | 18 +-- docs/site/docs/verification/verify-markup.md | 6 +- src/bunit/Asserting/CompareToExtensions.cs | 10 +- .../MarkupMatchesAssertExtensions.cs | 40 +++--- .../IRefreshableElementCollection.cs | 4 +- .../InputFile/InputFileExtensions.cs | 2 +- .../Internal/CssSelectorElementFactory.cs | 4 +- .../Internal/RefreshableElementCollection.cs | 4 +- .../RenderedComponentRenderExtensions.cs | 10 +- .../Extensions/RenderedFragmentExtensions.cs | 22 +-- .../RenderedFragmentInvokeAsyncExtensions.cs | 10 +- .../Extensions/TestContextRenderExtensions.cs | 8 +- .../Extensions/TestRendererExtensions.cs | 12 +- ...tWaitForHelperExtensions.WaitForElement.cs | 32 ++--- ...entWaitForHelperExtensions.WaitForState.cs | 8 +- .../WaitForHelpers/WaitForAssertionHelper.cs | 2 +- .../WaitForHelpers/WaitForElementHelper.cs | 2 +- .../WaitForHelpers/WaitForElementsHelper.cs | 2 +- .../WaitForHelpers/WaitForHelper.cs | 6 +- .../WaitForHelpers/WaitForStateHelper.cs | 2 +- src/bunit/IRenderedComponent.cs | 11 -- src/bunit/IRenderedFragment.cs | 56 -------- .../Rendering/ComponentDisposedException.cs | 2 +- .../Rendering/IRenderedComponentActivator.cs | 14 +- src/bunit/Rendering/RenderEvent.cs | 2 +- src/bunit/Rendering/RenderedComponent.cs | 16 ++- .../Rendering/RenderedComponentActivator.cs | 6 +- src/bunit/Rendering/RenderedFragment.cs | 133 +++++++++--------- src/bunit/Rendering/TestRenderer.cs | 22 +-- src/bunit/TestContext.cs | 16 +-- src/bunit/TestContextWrapper.cs | 14 +- .../CompareToDiffingExtensionsTest.cs | 4 +- .../MarkupMatchesAssertExtensionsTest.cs | 22 +-- ...omponentParameterCollectionBuilderTests.cs | 14 +- .../ComponentParameterCollectionTest.cs | 2 +- .../ComponentParameterFactoryTest.cs | 2 +- .../TriggerEventSpy.cs | 4 +- .../Extensions/InputFile/InputFileTests.cs | 2 +- .../bunit.tests/Rendering/TestRendererTest.cs | 2 +- .../TestUtilities/MockingHelpers.cs | 22 +++ 50 files changed, 300 insertions(+), 334 deletions(-) delete mode 100644 src/bunit/IRenderedComponent.cs delete mode 100644 src/bunit/IRenderedFragment.cs diff --git a/MIGRATION.md b/MIGRATION.md index 675181a74..29339e908 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -2,7 +2,7 @@ This document describes the changes that need to be made to migrate from bUnit 1.x to 2.x. ## Removal of `GetChangesSinceFirstRender` and `GetChangesSinceLastRender` methods -The `GetChangesSinceFirstRender` and `GetChangesSinceLastRender` methods have been removed from `IRenderedComponent`. There is no one-to-one replacement for these methods, but the general idea is to select the HTML in question via `Find` and assert against that. +The `GetChangesSinceFirstRender` and `GetChangesSinceLastRender` methods have been removed from `RenderedComponent`. There is no one-to-one replacement for these methods, but the general idea is to select the HTML in question via `Find` and assert against that. Alternatively, the `IRenderFragment` still offers the `OnMarkupUpdated` event, which can be used to assert against the markup after a render. @@ -28,8 +28,8 @@ The `bunit.core` and `bunit.web` packages have been merged into a single `bunit` ## Removal of unneeded abstraction -### `IRenderedComponentBase` and `IRenderedFragmentBase` -`IRenderedComponentBase` and `IRenderedFragmentBase` have been removed. They were used to provide a common base class for `IRenderedComponent` and `IRenderedFragment`, but this is no longer needed (due to the merge of the project). If you used either of these interfaces, you should replace them with `IRenderedComponent` and `IRenderedFragment` respectively. +### `IRenderedComponentBase` and `RenderedFragmentBase` +`IRenderedComponentBase` and `RenderedFragmentBase` have been removed. They were used to provide a common base class for `RenderedComponent` and `RenderedFragment`, but this is no longer needed (due to the merge of the project). If you used either of these interfaces, you should replace them with `RenderedComponent` and `RenderedFragment` respectively. ### `WebTestRender` merged into `TestRender` The `WebTestRender` class has been merged into the `TestRender` class. If you used `WebTestRender`, you should replace it with `TestRender`. diff --git a/docs/site/docs/getting-started/writing-tests.md b/docs/site/docs/getting-started/writing-tests.md index 1c9663b4e..3b89e9a9e 100644 --- a/docs/site/docs/getting-started/writing-tests.md +++ b/docs/site/docs/getting-started/writing-tests.md @@ -9,7 +9,7 @@ Testing Blazor components is a little different from testing regular C# classes: Use **bUnit** to render the component under test, pass in its parameters, inject required services, and access the rendered component instance and the markup it has produced. -Rendering a component happens through bUnit's . The result of the rendering is an `IRenderedComponent`, referred to as a "rendered component", that provides access to the component instance and the markup produced by the component. +Rendering a component happens through bUnit's . The result of the rendering is an `RenderedComponent`, referred to as a "rendered component", that provides access to the component instance and the markup produced by the component. ## Write tests in `.cs` or `.razor` files diff --git a/docs/site/docs/interaction/awaiting-async-state.md b/docs/site/docs/interaction/awaiting-async-state.md index 2d7c668af..165a59e16 100644 --- a/docs/site/docs/interaction/awaiting-async-state.md +++ b/docs/site/docs/interaction/awaiting-async-state.md @@ -9,13 +9,13 @@ A test can fail if a component performs asynchronous renders. This may be due to You need to handle this specifically in your tests because tests execute in the test framework's synchronization context and the test renderer executes renders in its own synchronization context. If you do not, you will likely experience tests that sometimes pass and sometimes fail. -bUnit comes with two methods that help to deal with this issue: the [`WaitForState()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForState(Bunit.IRenderedFragment,Func{System.Boolean},System.Nullable{TimeSpan})) method covered on this page, and the [`WaitForAssertion()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForAssertion(Bunit.IRenderedFragment,Action,System.Nullable{TimeSpan})) method covered on the page. +bUnit comes with two methods that help to deal with this issue: the [`WaitForState()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForState(Bunit.RenderedFragment,Func{System.Boolean},System.Nullable{TimeSpan})) method covered on this page, and the [`WaitForAssertion()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForAssertion(Bunit.RenderedFragment,Action,System.Nullable{TimeSpan})) method covered on the page. Let's start by taking a look at the `WaitForState` method in more detail. ## Waiting for state using `WaitForState` -The [`WaitForState(Func, TimeSpan?)`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForState(Bunit.IRenderedFragment,Func{System.Boolean},System.Nullable{TimeSpan})) method can be used to block and wait in a test method, until the provided predicate returns true or the timeout is reached. (The default timeout is one second.) +The [`WaitForState(Func, TimeSpan?)`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForState(Bunit.RenderedFragment,Func{System.Boolean},System.Nullable{TimeSpan})) method can be used to block and wait in a test method, until the provided predicate returns true or the timeout is reached. (The default timeout is one second.) > [!NOTE] > The `WaitForState()` method will try the predicate passed to it when the `WaitForState()` method is called, and every time the component under test renders. diff --git a/docs/site/docs/interaction/dispose-components.md b/docs/site/docs/interaction/dispose-components.md index b996b67a7..984e5389c 100644 --- a/docs/site/docs/interaction/dispose-components.md +++ b/docs/site/docs/interaction/dispose-components.md @@ -13,7 +13,7 @@ The following example of this: [!code-csharp[](../../../samples/tests/xunit/DisposeComponentsTest.cs#L13-L22)] > [!WARNING] -> For `IAsyncDisposable` (since .net5) relying on [`WaitForState()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForState(Bunit.IRenderedFragment,Func{System.Boolean},System.Nullable{TimeSpan})) or [`WaitForAssertion()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForAssertion(Bunit.IRenderedFragment,Action,System.Nullable{TimeSpan})) will not work as a disposed component will not trigger a new render cycle. +> For `IAsyncDisposable` (since .net5) relying on [`WaitForState()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForState(Bunit.RenderedFragment,Func{System.Boolean},System.Nullable{TimeSpan})) or [`WaitForAssertion()`](xref:Bunit.RenderedFragmentWaitForHelperExtensions.WaitForAssertion(Bunit.RenderedFragment,Action,System.Nullable{TimeSpan})) will not work as a disposed component will not trigger a new render cycle. ## Checking for exceptions `Dispose` as well as `DisposeAsync` can throw exceptions which can be asserted as well. If a component under test throws an exception in `Dispose` the [`DisposeComponents`](xref:Bunit.TestContext.DisposeComponents) will throw the exception to the user code: diff --git a/docs/site/docs/interaction/trigger-event-handlers.md b/docs/site/docs/interaction/trigger-event-handlers.md index 8b1245ccd..89e148f48 100644 --- a/docs/site/docs/interaction/trigger-event-handlers.md +++ b/docs/site/docs/interaction/trigger-event-handlers.md @@ -23,7 +23,7 @@ bUnit comes with event dispatch helper methods that makes it possible to invoke - [Progress events](xref:Bunit.ProgressEventDispatchExtensions) - [Touch event](xref:Bunit.TouchEventDispatchExtensions) -To use these, first find the element in the component under test where the event handler is bound. This is usually done with the [`Find(string cssSelector)`](xref:Bunit.RenderedFragmentExtensions.Find(Bunit.IRenderedFragment,System.String)) method. Next, invoke the event dispatch helper method of choice. +To use these, first find the element in the component under test where the event handler is bound. This is usually done with the [`Find(string cssSelector)`](xref:Bunit.RenderedFragmentExtensions.Find(Bunit.RenderedFragment,System.String)) method. Next, invoke the event dispatch helper method of choice. The following section demonstrates how to do this... @@ -49,7 +49,7 @@ To trigger the `@onclick` `ClickHandler` event handler method in the `` This is what happens in the test: -1. In the arrange step of the test, the `` component is rendered and the ` /// The rendered component to re-render. /// The type of the component. - public static void Render(this IRenderedComponent renderedComponent) + public static void Render(this RenderedComponent renderedComponent) where TComponent : IComponent => SetParametersAndRender(renderedComponent, ParameterView.Empty); @@ -23,7 +23,7 @@ public static void Render(this IRenderedComponent render /// The rendered component to re-render with new parameters. /// Parameters to pass to the component upon rendered. /// The type of the component. - public static void SetParametersAndRender(this IRenderedComponent renderedComponent, ParameterView parameters) + public static void SetParametersAndRender(this RenderedComponent renderedComponent, ParameterView parameters) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(renderedComponent); @@ -46,7 +46,7 @@ public static void SetParametersAndRender(this IRenderedComponentThe rendered component to re-render with new parameters. /// Parameters to pass to the component upon rendered. /// The type of the component. - public static void SetParametersAndRender(this IRenderedComponent renderedComponent, params ComponentParameter[] parameters) + public static void SetParametersAndRender(this RenderedComponent renderedComponent, params ComponentParameter[] parameters) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(renderedComponent); @@ -61,7 +61,7 @@ public static void SetParametersAndRender(this IRenderedComponentThe rendered component to re-render with new parameters. /// An action that receives a . /// The type of the component. - public static void SetParametersAndRender(this IRenderedComponent renderedComponent, Action> parameterBuilder) + public static void SetParametersAndRender(this RenderedComponent renderedComponent, Action> parameterBuilder) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(renderedComponent); diff --git a/src/bunit/Extensions/RenderedFragmentExtensions.cs b/src/bunit/Extensions/RenderedFragmentExtensions.cs index 83732d052..e2f6d0070 100644 --- a/src/bunit/Extensions/RenderedFragmentExtensions.cs +++ b/src/bunit/Extensions/RenderedFragmentExtensions.cs @@ -5,7 +5,7 @@ namespace Bunit; /// -/// Helper methods for querying . +/// Helper methods for querying . /// public static class RenderedFragmentExtensions { @@ -16,7 +16,7 @@ public static class RenderedFragmentExtensions /// /// The rendered fragment to search. /// The group of selectors to use. - public static IElement Find(this IRenderedFragment renderedFragment, string cssSelector) + public static IElement Find(this RenderedFragment renderedFragment, string cssSelector) { ArgumentNullException.ThrowIfNull(renderedFragment); @@ -37,7 +37,7 @@ public static IElement Find(this IRenderedFragment renderedFragment, string cssS /// The group of selectors to use. /// If true, the returned will automatically refresh its s whenever the changes. /// An , that can be refreshed to execute the search again. - public static IRefreshableElementCollection FindAll(this IRenderedFragment renderedFragment, string cssSelector, bool enableAutoRefresh = false) + public static IRefreshableElementCollection FindAll(this RenderedFragment renderedFragment, string cssSelector, bool enableAutoRefresh = false) { ArgumentNullException.ThrowIfNull(renderedFragment); return new RefreshableElementCollection(renderedFragment, cssSelector) { EnableAutoRefresh = enableAutoRefresh }; @@ -45,12 +45,12 @@ public static IRefreshableElementCollection FindAll(this IRenderedFrag /// /// Finds the first component of type in the render tree of - /// this . + /// this . /// /// Type of component to find. /// Thrown if a component of type was not found in the render tree. - /// The . - public static IRenderedComponent FindComponent(this IRenderedFragment renderedFragment) + /// The . + public static RenderedComponent FindComponent(this RenderedFragment renderedFragment) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(renderedFragment); @@ -61,11 +61,11 @@ public static IRenderedComponent FindComponent(this IRen /// /// Finds all components of type in the render tree of - /// this , in depth-first order. + /// this , in depth-first order. /// /// Type of components to find. - /// The s. - public static IReadOnlyList> FindComponents(this IRenderedFragment renderedFragment) + /// The s. + public static IReadOnlyList> FindComponents(this RenderedFragment renderedFragment) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(renderedFragment); @@ -73,7 +73,7 @@ public static IReadOnlyList> FindComponents().Renderer; var components = renderer.FindComponents(renderedFragment); - return components.OfType>().ToArray(); + return components.OfType>().ToArray(); } /// @@ -83,6 +83,6 @@ public static IReadOnlyList> FindComponentsThe type of component to look for in the render tree. /// The render tree to search. /// True if the contains the ; otherwise false. - public static bool HasComponent(this IRenderedFragment renderedFragment) + public static bool HasComponent(this RenderedFragment renderedFragment) where TComponent : IComponent => FindComponents(renderedFragment).Count > 0; } diff --git a/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs b/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs index 88abb6cf2..232eaa875 100644 --- a/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs +++ b/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs @@ -3,7 +3,7 @@ namespace Bunit; /// -/// InvokeAsync extensions methods on . +/// InvokeAsync extensions methods on . /// public static class RenderedFragmentInvokeAsyncExtensions { @@ -13,7 +13,7 @@ public static class RenderedFragmentInvokeAsyncExtensions /// The rendered fragment whose dispatcher to invoke with. /// The work item to execute on the renderer's thread. /// A that will be completed when the action has finished executing or is suspended by an asynchronous operation. - public static Task InvokeAsync(this IRenderedFragment renderedFragment, Action workItem) + public static Task InvokeAsync(this RenderedFragment renderedFragment, Action workItem) { ArgumentNullException.ThrowIfNull(renderedFragment); @@ -31,7 +31,7 @@ public static Task InvokeAsync(this IRenderedFragment renderedFragment, Action w /// The rendered component whose dispatcher to invoke with. /// The work item to execute on the renderer's thread. /// A that will be completed when the action has finished executing. - public static Task InvokeAsync(this IRenderedFragment renderedFragment, Func workItem) + public static Task InvokeAsync(this RenderedFragment renderedFragment, Func workItem) { ArgumentNullException.ThrowIfNull(renderedFragment); @@ -49,7 +49,7 @@ public static Task InvokeAsync(this IRenderedFragment renderedFragment, FuncThe rendered component whose dispatcher to invoke with. /// The work item to execute on the renderer's thread. /// A that will be completed when the action has finished executing, with the return value from . - public static Task InvokeAsync(this IRenderedFragment renderedFragment, Func workItem) + public static Task InvokeAsync(this RenderedFragment renderedFragment, Func workItem) { ArgumentNullException.ThrowIfNull(renderedFragment); @@ -67,7 +67,7 @@ public static Task InvokeAsync(this IRenderedFragment renderedFragment, Fu /// The rendered component whose dispatcher to invoke with. /// The work item to execute on the renderer's thread. /// A that will be completed when the action has finished executing, with the return value from . - public static Task InvokeAsync(this IRenderedFragment renderedFragment, Func> workItem) + public static Task InvokeAsync(this RenderedFragment renderedFragment, Func> workItem) { ArgumentNullException.ThrowIfNull(renderedFragment); diff --git a/src/bunit/Extensions/TestContextRenderExtensions.cs b/src/bunit/Extensions/TestContextRenderExtensions.cs index cd11843fa..d2d369970 100644 --- a/src/bunit/Extensions/TestContextRenderExtensions.cs +++ b/src/bunit/Extensions/TestContextRenderExtensions.cs @@ -13,8 +13,8 @@ public static class TestContextRenderExtensions /// The type of component to render. /// Test context to use to render with. /// The that contains a declaration of the component. - /// A . - public static IRenderedComponent RenderInsideRenderTree(this TestContext testContext, RenderFragment renderFragment) + /// A . + public static RenderedComponent RenderInsideRenderTree(this TestContext testContext, RenderFragment renderFragment) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(testContext); @@ -28,8 +28,8 @@ public static IRenderedComponent RenderInsideRenderTree( /// /// Test context to use to render with. /// The to render. - /// A . - public static IRenderedFragment RenderInsideRenderTree(this TestContext testContext, RenderFragment renderFragment) + /// A . + public static RenderedFragment RenderInsideRenderTree(this TestContext testContext, RenderFragment renderFragment) { ArgumentNullException.ThrowIfNull(testContext); diff --git a/src/bunit/Extensions/TestRendererExtensions.cs b/src/bunit/Extensions/TestRendererExtensions.cs index 074028a38..31d9817f7 100644 --- a/src/bunit/Extensions/TestRendererExtensions.cs +++ b/src/bunit/Extensions/TestRendererExtensions.cs @@ -14,14 +14,14 @@ public static class TestRendererExtensions /// The type of component to render. /// The renderer to use. /// The parameters to pass to the component. - /// A that provides access to the rendered component. - public static IRenderedComponent RenderComponent(this TestRenderer renderer, params ComponentParameter[] parameters) + /// A that provides access to the rendered component. + public static RenderedComponent RenderComponent(this TestRenderer renderer, params ComponentParameter[] parameters) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(renderer); var resultBase = renderer.RenderComponent(new ComponentParameterCollection { parameters }); - if (resultBase is IRenderedComponent result) + if (resultBase is RenderedComponent result) return result; throw new InvalidOperationException($"The renderer did not produce the expected type. Is the test renderer using the expected {nameof(IRenderedComponentActivator)}?"); @@ -33,8 +33,8 @@ public static IRenderedComponent RenderComponent(this Te /// The type of component to render. /// The renderer to use. /// The a builder to create parameters to pass to the component. - /// A that provides access to the rendered component. - public static IRenderedComponent RenderComponent(this TestRenderer renderer, Action> parameterBuilder) + /// A that provides access to the rendered component. + public static RenderedComponent RenderComponent(this TestRenderer renderer, Action> parameterBuilder) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(renderer); @@ -42,7 +42,7 @@ public static IRenderedComponent RenderComponent(this Te var builder = new ComponentParameterCollectionBuilder(parameterBuilder); var resultBase = renderer.RenderComponent(builder.Build()); - if (resultBase is IRenderedComponent result) + if (resultBase is RenderedComponent result) return result; throw new InvalidOperationException($"The renderer did not produce the expected type. Is the test renderer using the expected {nameof(IRenderedComponentActivator)}?"); diff --git a/src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForElement.cs b/src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForElement.cs index f6fac5d47..910374624 100644 --- a/src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForElement.cs +++ b/src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForElement.cs @@ -17,7 +17,7 @@ public static partial class RenderedFragmentWaitForHelperExtensions /// The CSS selector to use to search for the element. /// Thrown if no elements is found matching the within the default timeout. See the inner exception for details. /// The . - public static IElement WaitForElement(this IRenderedFragment renderedFragment, string cssSelector) + public static IElement WaitForElement(this RenderedFragment renderedFragment, string cssSelector) => WaitForElementCore(renderedFragment, cssSelector, timeout: null); /// @@ -29,7 +29,7 @@ public static IElement WaitForElement(this IRenderedFragment renderedFragment, s /// The maximum time to wait for the element to appear. /// Thrown if no elements is found matching the within the default timeout. See the inner exception for details. /// The . - public static IElement WaitForElement(this IRenderedFragment renderedFragment, string cssSelector, TimeSpan timeout) + public static IElement WaitForElement(this RenderedFragment renderedFragment, string cssSelector, TimeSpan timeout) => WaitForElementCore(renderedFragment, cssSelector, timeout: timeout); /// @@ -40,7 +40,7 @@ public static IElement WaitForElement(this IRenderedFragment renderedFragment, s /// The CSS selector to use to search for elements. /// Thrown if no elements is found matching the within the default timeout. /// The . - public static IRefreshableElementCollection WaitForElements(this IRenderedFragment renderedFragment, string cssSelector) + public static IRefreshableElementCollection WaitForElements(this RenderedFragment renderedFragment, string cssSelector) => WaitForElementsCore(renderedFragment, cssSelector, matchElementCount: null, timeout: null); /// @@ -52,7 +52,7 @@ public static IRefreshableElementCollection WaitForElements(this IRend /// The exact number of elements to that the should match. /// Thrown if no elements is found matching the within the default timeout. /// The . - public static IRefreshableElementCollection WaitForElements(this IRenderedFragment renderedFragment, string cssSelector, int matchElementCount) + public static IRefreshableElementCollection WaitForElements(this RenderedFragment renderedFragment, string cssSelector, int matchElementCount) => WaitForElementsCore(renderedFragment, cssSelector, matchElementCount: matchElementCount, timeout: null); /// @@ -64,7 +64,7 @@ public static IRefreshableElementCollection WaitForElements(this IRend /// The maximum time to wait for elements to appear. /// Thrown if no elements is found matching the within the default timeout. /// The . - public static IRefreshableElementCollection WaitForElements(this IRenderedFragment renderedFragment, string cssSelector, TimeSpan timeout) + public static IRefreshableElementCollection WaitForElements(this RenderedFragment renderedFragment, string cssSelector, TimeSpan timeout) => WaitForElementsCore(renderedFragment, cssSelector, matchElementCount: null, timeout: timeout); /// @@ -77,7 +77,7 @@ public static IRefreshableElementCollection WaitForElements(this IRend /// The maximum time to wait for elements to appear. /// Thrown if no elements is found matching the within the default timeout. /// The . - public static IRefreshableElementCollection WaitForElements(this IRenderedFragment renderedFragment, string cssSelector, int matchElementCount, TimeSpan timeout) + public static IRefreshableElementCollection WaitForElements(this RenderedFragment renderedFragment, string cssSelector, int matchElementCount, TimeSpan timeout) => WaitForElementsCore(renderedFragment, cssSelector, matchElementCount: matchElementCount, timeout: timeout); /// @@ -88,7 +88,7 @@ public static IRefreshableElementCollection WaitForElements(this IRend /// The CSS selector to use to search for the element. /// Thrown if no elements is found matching the within the default timeout. See the inner exception for details. /// The . - internal static Task WaitForElementAsync(this IRenderedFragment renderedFragment, string cssSelector) + internal static Task WaitForElementAsync(this RenderedFragment renderedFragment, string cssSelector) => WaitForElementCoreAsync(renderedFragment, cssSelector, timeout: null); /// @@ -100,7 +100,7 @@ internal static Task WaitForElementAsync(this IRenderedFragment render /// The maximum time to wait for the element to appear. /// Thrown if no elements is found matching the within the default timeout. See the inner exception for details. /// The . - internal static Task WaitForElementAsync(this IRenderedFragment renderedFragment, string cssSelector, TimeSpan timeout) + internal static Task WaitForElementAsync(this RenderedFragment renderedFragment, string cssSelector, TimeSpan timeout) => WaitForElementCoreAsync(renderedFragment, cssSelector, timeout: timeout); /// @@ -112,7 +112,7 @@ internal static Task WaitForElementAsync(this IRenderedFragment render /// The exact number of elements to that the should match. /// Thrown if no elements is found matching the within the default timeout. /// The . - internal static Task> WaitForElementsAsync(this IRenderedFragment renderedFragment, string cssSelector, int matchElementCount) + internal static Task> WaitForElementsAsync(this RenderedFragment renderedFragment, string cssSelector, int matchElementCount) => WaitForElementsCoreAsync(renderedFragment, cssSelector, matchElementCount: matchElementCount, timeout: null); /// @@ -124,7 +124,7 @@ internal static Task> WaitForElementsAsy /// The maximum time to wait for elements to appear. /// Thrown if no elements is found matching the within the default timeout. /// The . - internal static Task> WaitForElementsAsync(this IRenderedFragment renderedFragment, string cssSelector, TimeSpan timeout) + internal static Task> WaitForElementsAsync(this RenderedFragment renderedFragment, string cssSelector, TimeSpan timeout) => WaitForElementsCoreAsync(renderedFragment, cssSelector, matchElementCount: null, timeout: timeout); /// @@ -137,7 +137,7 @@ internal static Task> WaitForElementsAsy /// The maximum time to wait for elements to appear. /// Thrown if no elements is found matching the within the default timeout. /// The . - internal static Task> WaitForElementsAsync(this IRenderedFragment renderedFragment, string cssSelector, int matchElementCount, TimeSpan timeout) + internal static Task> WaitForElementsAsync(this RenderedFragment renderedFragment, string cssSelector, int matchElementCount, TimeSpan timeout) => WaitForElementsCoreAsync(renderedFragment, cssSelector, matchElementCount: matchElementCount, timeout: timeout); /// @@ -148,10 +148,10 @@ internal static Task> WaitForElementsAsy /// The CSS selector to use to search for elements. /// Thrown if no elements is found matching the within the default timeout. /// The . - internal static Task> WaitForElementsAsync(this IRenderedFragment renderedFragment, string cssSelector) + internal static Task> WaitForElementsAsync(this RenderedFragment renderedFragment, string cssSelector) => WaitForElementsCoreAsync(renderedFragment, cssSelector, matchElementCount: null, timeout: null); - private static IElement WaitForElementCore(this IRenderedFragment renderedFragment, string cssSelector, TimeSpan? timeout) + private static IElement WaitForElementCore(this RenderedFragment renderedFragment, string cssSelector, TimeSpan? timeout) { using var waiter = new WaitForElementHelper(renderedFragment, cssSelector, timeout); @@ -168,7 +168,7 @@ private static IElement WaitForElementCore(this IRenderedFragment renderedFragme } } - private static async Task WaitForElementCoreAsync(this IRenderedFragment renderedFragment, string cssSelector, TimeSpan? timeout) + private static async Task WaitForElementCoreAsync(this RenderedFragment renderedFragment, string cssSelector, TimeSpan? timeout) { using var waiter = new WaitForElementHelper(renderedFragment, cssSelector, timeout); @@ -176,7 +176,7 @@ private static async Task WaitForElementCoreAsync(this IRenderedFragme } private static IRefreshableElementCollection WaitForElementsCore( - this IRenderedFragment renderedFragment, + this RenderedFragment renderedFragment, string cssSelector, int? matchElementCount, TimeSpan? timeout) @@ -197,7 +197,7 @@ private static IRefreshableElementCollection WaitForElementsCore( } private static async Task> WaitForElementsCoreAsync( - this IRenderedFragment renderedFragment, + this RenderedFragment renderedFragment, string cssSelector, int? matchElementCount, TimeSpan? timeout) diff --git a/src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForState.cs b/src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForState.cs index f2eb51d49..4cdfdfecc 100644 --- a/src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForState.cs +++ b/src/bunit/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.WaitForState.cs @@ -23,7 +23,7 @@ public static partial class RenderedFragmentWaitForHelperExtensions /// /// If a debugger is attached the timeout is set to , giving the possibility to debug without the timeout triggering. /// - public static void WaitForState(this IRenderedFragment renderedFragment, Func statePredicate, TimeSpan? timeout = null) + public static void WaitForState(this RenderedFragment renderedFragment, Func statePredicate, TimeSpan? timeout = null) { using var waiter = new WaitForStateHelper(renderedFragment, statePredicate, timeout); @@ -48,7 +48,7 @@ public static void WaitForState(this IRenderedFragment renderedFragment, FuncThe predicate to invoke after each render, which must returns true when the desired state has been reached. /// The maximum time to wait for the desired state. /// Thrown if the throw an exception during invocation, or if the timeout has been reached. See the inner exception for details. - internal static async Task WaitForStateAsync(this IRenderedFragment renderedFragment, Func statePredicate, TimeSpan? timeout = null) + internal static async Task WaitForStateAsync(this RenderedFragment renderedFragment, Func statePredicate, TimeSpan? timeout = null) { using var waiter = new WaitForStateHelper(renderedFragment, statePredicate, timeout); @@ -66,7 +66,7 @@ internal static async Task WaitForStateAsync(this IRenderedFragment renderedFrag /// The maximum time to attempt the verification. /// Thrown if the timeout has been reached. See the inner exception to see the captured assertion exception. [AssertionMethod] - public static void WaitForAssertion(this IRenderedFragment renderedFragment, Action assertion, TimeSpan? timeout = null) + public static void WaitForAssertion(this RenderedFragment renderedFragment, Action assertion, TimeSpan? timeout = null) { using var waiter = new WaitForAssertionHelper(renderedFragment, assertion, timeout); @@ -91,7 +91,7 @@ public static void WaitForAssertion(this IRenderedFragment renderedFragment, Act /// The maximum time to attempt the verification. /// Thrown if the timeout has been reached. See the inner exception to see the captured assertion exception. [AssertionMethod] - internal static async Task WaitForAssertionAsync(this IRenderedFragment renderedFragment, Action assertion, TimeSpan? timeout = null) + internal static async Task WaitForAssertionAsync(this RenderedFragment renderedFragment, Action assertion, TimeSpan? timeout = null) { using var waiter = new WaitForAssertionHelper(renderedFragment, assertion, timeout); diff --git a/src/bunit/Extensions/WaitForHelpers/WaitForAssertionHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForAssertionHelper.cs index a5e002a96..e6c73d00c 100644 --- a/src/bunit/Extensions/WaitForHelpers/WaitForAssertionHelper.cs +++ b/src/bunit/Extensions/WaitForHelpers/WaitForAssertionHelper.cs @@ -26,7 +26,7 @@ public class WaitForAssertionHelper : WaitForHelper /// /// If a debugger is attached the timeout is set to , giving the possibility to debug without the timeout triggering. /// - public WaitForAssertionHelper(IRenderedFragment renderedFragment, Action assertion, TimeSpan? timeout = null) + public WaitForAssertionHelper(RenderedFragment renderedFragment, Action assertion, TimeSpan? timeout = null) : base( renderedFragment, () => diff --git a/src/bunit/Extensions/WaitForHelpers/WaitForElementHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForElementHelper.cs index 829237716..3e60fda5f 100644 --- a/src/bunit/Extensions/WaitForHelpers/WaitForElementHelper.cs +++ b/src/bunit/Extensions/WaitForHelpers/WaitForElementHelper.cs @@ -15,7 +15,7 @@ internal class WaitForElementHelper : WaitForHelper /// protected override bool StopWaitingOnCheckException => false; - public WaitForElementHelper(IRenderedFragment renderedFragment, string cssSelector, TimeSpan? timeout = null) + public WaitForElementHelper(RenderedFragment renderedFragment, string cssSelector, TimeSpan? timeout = null) : base(renderedFragment, () => { var element = renderedFragment.Find(cssSelector); diff --git a/src/bunit/Extensions/WaitForHelpers/WaitForElementsHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForElementsHelper.cs index 179fdec55..dac1d6e62 100644 --- a/src/bunit/Extensions/WaitForHelpers/WaitForElementsHelper.cs +++ b/src/bunit/Extensions/WaitForHelpers/WaitForElementsHelper.cs @@ -21,7 +21,7 @@ internal class WaitForElementsHelper : WaitForHelper protected override bool StopWaitingOnCheckException => true; - public WaitForElementsHelper(IRenderedFragment renderedFragment, string cssSelector, int? matchElementCount, TimeSpan? timeout = null) + public WaitForElementsHelper(RenderedFragment renderedFragment, string cssSelector, int? matchElementCount, TimeSpan? timeout = null) : base(renderedFragment, () => { var elements = renderedFragment.FindAll(cssSelector); diff --git a/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs index 650ccccea..41537f974 100644 --- a/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs +++ b/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs @@ -5,7 +5,7 @@ namespace Bunit.Extensions.WaitForHelpers; /// -/// Represents a helper class that can wait for a render notifications from a type, +/// Represents a helper class that can wait for a render notifications from a type, /// until a specific timeout is reached. /// public abstract class WaitForHelper : IDisposable @@ -13,7 +13,7 @@ public abstract class WaitForHelper : IDisposable private readonly Timer timer; private readonly TaskCompletionSource checkPassedCompletionSource; private readonly Func<(bool CheckPassed, T Content)> completeChecker; - private readonly IRenderedFragment renderedFragment; + private readonly RenderedFragment renderedFragment; private readonly ILogger> logger; private readonly TestRenderer renderer; private bool isDisposed; @@ -46,7 +46,7 @@ public abstract class WaitForHelper : IDisposable /// Initializes a new instance of the class. /// protected WaitForHelper( - IRenderedFragment renderedFragment, + RenderedFragment renderedFragment, Func<(bool CheckPassed, T Content)> completeChecker, TimeSpan? timeout = null) { diff --git a/src/bunit/Extensions/WaitForHelpers/WaitForStateHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForStateHelper.cs index 4ee219c02..c07be3cc9 100644 --- a/src/bunit/Extensions/WaitForHelpers/WaitForStateHelper.cs +++ b/src/bunit/Extensions/WaitForHelpers/WaitForStateHelper.cs @@ -29,7 +29,7 @@ public class WaitForStateHelper : WaitForHelper /// The predicate to invoke after each render, which must returns true when the desired state has been reached. /// The maximum time to wait for the desired state. /// Thrown if the throw an exception during invocation, or if the timeout has been reached. See the inner exception for details. - public WaitForStateHelper(IRenderedFragment renderedFragment, Func statePredicate, TimeSpan? timeout = null) + public WaitForStateHelper(RenderedFragment renderedFragment, Func statePredicate, TimeSpan? timeout = null) : base(renderedFragment, () => (statePredicate(), default), timeout) { } diff --git a/src/bunit/IRenderedComponent.cs b/src/bunit/IRenderedComponent.cs deleted file mode 100644 index 175535f1c..000000000 --- a/src/bunit/IRenderedComponent.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Bunit; - -/// -public interface IRenderedComponent : IRenderedFragment - where TComponent : IComponent -{ - /// - /// Gets the component under test. - /// - TComponent Instance { get; } -} diff --git a/src/bunit/IRenderedFragment.cs b/src/bunit/IRenderedFragment.cs deleted file mode 100644 index ebf887a3d..000000000 --- a/src/bunit/IRenderedFragment.cs +++ /dev/null @@ -1,56 +0,0 @@ -using AngleSharp.Dom; -using Bunit.Rendering; - -namespace Bunit; - -/// -/// Represents a rendered fragment. -/// -public interface IRenderedFragment : IDisposable -{ - /// - /// Gets the total number times the fragment has been through its render life-cycle. - /// - int RenderCount { get; } - - /// - /// Gets a value indicating whether the rendered component or fragment has been disposed by the . - /// - bool IsDisposed { get; } - - /// - /// Gets the id of the rendered component or fragment. - /// - int ComponentId { get; } - - /// - /// Called by the owning when it finishes a render. - /// - /// A that represents a render. - void OnRender(RenderEvent renderEvent); - - /// - /// Gets the used when rendering the component. - /// - IServiceProvider Services { get; } - - /// - /// Adds or removes an event handler that will be triggered after each render of this . - /// - event EventHandler OnAfterRender; - /// - /// An event that is raised after the markup of the is updated. - /// - event EventHandler OnMarkupUpdated; - - /// - /// Gets the HTML markup from the rendered fragment/component. - /// - string Markup { get; } - - /// - /// Gets the AngleSharp based - /// on the HTML markup from the rendered fragment/component. - /// - INodeList Nodes { get; } -} diff --git a/src/bunit/Rendering/ComponentDisposedException.cs b/src/bunit/Rendering/ComponentDisposedException.cs index 634d311f1..8784d71f2 100644 --- a/src/bunit/Rendering/ComponentDisposedException.cs +++ b/src/bunit/Rendering/ComponentDisposedException.cs @@ -1,7 +1,7 @@ namespace Bunit.Rendering; /// -/// Represents an exception that is thrown when a 's +/// Represents an exception that is thrown when a 's /// properties is accessed after the underlying component has been disposed by the renderer. /// [Serializable] diff --git a/src/bunit/Rendering/IRenderedComponentActivator.cs b/src/bunit/Rendering/IRenderedComponentActivator.cs index faf6b36dd..dceb1ff32 100644 --- a/src/bunit/Rendering/IRenderedComponentActivator.cs +++ b/src/bunit/Rendering/IRenderedComponentActivator.cs @@ -1,25 +1,25 @@ namespace Bunit.Rendering; /// -/// Represents an activator for and types. +/// Represents an activator for and types. /// public interface IRenderedComponentActivator { /// - /// Creates an with the specified . + /// Creates an with the specified . /// - IRenderedFragment CreateRenderedFragment(int componentId); + RenderedFragment CreateRenderedFragment(int componentId); /// - /// Creates an with the specified . + /// Creates an with the specified . /// - IRenderedComponent CreateRenderedComponent(int componentId) + RenderedComponent CreateRenderedComponent(int componentId) where TComponent : IComponent; /// - /// Creates an with the specified , + /// Creates an with the specified , /// , and . /// - IRenderedComponent CreateRenderedComponent(int componentId, TComponent component, RenderTreeFrameDictionary componentFrames) + RenderedComponent CreateRenderedComponent(int componentId, TComponent component, RenderTreeFrameDictionary componentFrames) where TComponent : IComponent; } diff --git a/src/bunit/Rendering/RenderEvent.cs b/src/bunit/Rendering/RenderEvent.cs index 9069cb786..eb88dac4d 100644 --- a/src/bunit/Rendering/RenderEvent.cs +++ b/src/bunit/Rendering/RenderEvent.cs @@ -20,7 +20,7 @@ public sealed class RenderEvent /// /// The to get the status for. /// A tuple of statuses indicating whether the rendered component rendered during the render cycle, if it changed or if it was disposed. - public (bool Rendered, bool Changed, bool Disposed) GetRenderStatus(IRenderedFragment renderedComponent) + public (bool Rendered, bool Changed, bool Disposed) GetRenderStatus(RenderedFragment renderedComponent) { ArgumentNullException.ThrowIfNull(renderedComponent); diff --git a/src/bunit/Rendering/RenderedComponent.cs b/src/bunit/Rendering/RenderedComponent.cs index 9ec4204a2..aa7f11f4a 100644 --- a/src/bunit/Rendering/RenderedComponent.cs +++ b/src/bunit/Rendering/RenderedComponent.cs @@ -1,15 +1,20 @@ using System.Diagnostics; +using Bunit.Rendering; -namespace Bunit.Rendering; +namespace Bunit; -/// +/// +/// Represents a rendered component. +/// [DebuggerDisplay("Component={typeof(TComponent).Name,nq},RenderCount={RenderCount}")] -internal sealed class RenderedComponent : RenderedFragment, IRenderedComponent +public sealed class RenderedComponent : RenderedFragment where TComponent : IComponent { private TComponent? instance; - /// + /// + /// Gets the component under test. + /// public TComponent Instance { get @@ -30,7 +35,8 @@ internal RenderedComponent(int componentId, TComponent instance, RenderTreeFrame UpdateMarkup(componentFrames); } - protected override void OnRender(RenderEvent renderEvent) + /// + protected override void OnRenderInternal(RenderEvent renderEvent) { // checks if this is the first render, and if it is // tries to find the TComponent in the render event diff --git a/src/bunit/Rendering/RenderedComponentActivator.cs b/src/bunit/Rendering/RenderedComponentActivator.cs index a557c2073..9b30f1418 100644 --- a/src/bunit/Rendering/RenderedComponentActivator.cs +++ b/src/bunit/Rendering/RenderedComponentActivator.cs @@ -16,16 +16,16 @@ public RenderedComponentActivator(IServiceProvider services) } /// - public IRenderedFragment CreateRenderedFragment(int componentId) + public RenderedFragment CreateRenderedFragment(int componentId) => new RenderedFragment(componentId, services); /// - public IRenderedComponent CreateRenderedComponent(int componentId) + public RenderedComponent CreateRenderedComponent(int componentId) where TComponent : IComponent => new RenderedComponent(componentId, services); /// - public IRenderedComponent CreateRenderedComponent(int componentId, TComponent component, RenderTreeFrameDictionary componentFrames) + public RenderedComponent CreateRenderedComponent(int componentId, TComponent component, RenderTreeFrameDictionary componentFrames) where TComponent : IComponent => new RenderedComponent(componentId, component, componentFrames, services); } diff --git a/src/bunit/Rendering/RenderedFragment.cs b/src/bunit/Rendering/RenderedFragment.cs index 8b5e30785..89248a674 100644 --- a/src/bunit/Rendering/RenderedFragment.cs +++ b/src/bunit/Rendering/RenderedFragment.cs @@ -1,74 +1,78 @@ using System.Diagnostics; -using AngleSharp.Diffing.Core; using AngleSharp.Dom; +using Bunit.Rendering; -namespace Bunit.Rendering; +namespace Bunit; -/// +/// +/// Represents a rendered fragment. +/// [DebuggerDisplay("Rendered:{RenderCount}")] -internal class RenderedFragment : IRenderedFragment +public class RenderedFragment : IDisposable { [SuppressMessage("Usage", "CA2213:Disposable fields should be disposed", Justification = "Owned by TestServiceProvider, disposed by it.")] private readonly BunitHtmlParser htmlParser; - private readonly object markupAccessLock = new(); private string markup = string.Empty; private INodeList? latestRenderNodes; - /// + /// + /// Adds or removes an event handler that will be triggered after each render of this . + /// public event EventHandler? OnAfterRender; - /// + /// + /// An event that is raised after the markup of the is updated. + /// public event EventHandler? OnMarkupUpdated; - /// + /// + /// Gets a value indicating whether the rendered component or fragment has been disposed by the . + /// public bool IsDisposed { get; private set; } - /// + /// + /// Gets the id of the rendered component or fragment. + /// public int ComponentId { get; protected set; } - /// + /// + /// Gets the HTML markup from the rendered fragment/component. + /// public string Markup { get { EnsureComponentNotDisposed(); - - // The lock prevents a race condition between the renderers thread - // and the test frameworks thread, where one might be reading the Markup - // while the other is updating it due to async code in a rendered component. - lock (markupAccessLock) - { - // Volatile read is necessary to ensure the updated markup - // is available across CPU cores. Without it, the pointer to the - // markup string can be stored in a CPUs register and not - // get updated when another CPU changes the string. - return Volatile.Read(ref markup); - } + // Volatile read is necessary to ensure the updated markup + // is available across CPU cores. Without it, the pointer to the + // markup string can be stored in a CPUs register and not + // get updated when another CPU changes the string. + return Volatile.Read(ref markup); } } - /// + /// + /// Gets the total number times the fragment has been through its render life-cycle. + /// public int RenderCount { get; protected set; } - /// + /// + /// Gets the AngleSharp based + /// on the HTML markup from the rendered fragment/component. + /// + [DebuggerBrowsable(DebuggerBrowsableState.Never)] public INodeList Nodes { get { EnsureComponentNotDisposed(); - - // The lock ensures that latest nodes is always based on the latest rendered markup. - lock (markupAccessLock) - { - if (latestRenderNodes is null) - latestRenderNodes = htmlParser.Parse(Markup); - - return latestRenderNodes; - } + return latestRenderNodes ??= htmlParser.Parse(Markup); } } - /// + /// + /// Gets the used when rendering the component. + /// public IServiceProvider Services { get; } internal RenderedFragment(int componentId, IServiceProvider service) @@ -78,8 +82,14 @@ internal RenderedFragment(int componentId, IServiceProvider service) htmlParser = Services.GetRequiredService(); } - void IRenderedFragment.OnRender(RenderEvent renderEvent) + /// + /// Called by the owning when it finishes a render. + /// + /// A that represents a render. + public void OnRender(RenderEvent renderEvent) { + ArgumentNullException.ThrowIfNull(renderEvent); + if (IsDisposed) return; @@ -91,21 +101,15 @@ void IRenderedFragment.OnRender(RenderEvent renderEvent) return; } - // The lock prevents a race condition between the renderers thread - // and the test frameworks thread, where one might be reading the Markup - // while the other is updating it due to async code in a rendered component. - lock (markupAccessLock) + if (rendered) + { + OnRenderInternal(renderEvent); + RenderCount++; + } + + if (changed) { - if (rendered) - { - OnRender(renderEvent); - RenderCount++; - } - - if (changed) - { - UpdateMarkup(renderEvent.Frames); - } + UpdateMarkup(renderEvent.Frames); } // The order here is important, since consumers of the events @@ -118,25 +122,25 @@ void IRenderedFragment.OnRender(RenderEvent renderEvent) OnAfterRender?.Invoke(this, EventArgs.Empty); } + /// + /// Updates the markup of the rendered fragment. + /// protected void UpdateMarkup(RenderTreeFrameDictionary framesCollection) { - // The lock prevents a race condition between the renderers thread - // and the test frameworks thread, where one might be reading the Markup - // while the other is updating it due to async code in a rendered component. - lock (markupAccessLock) - { - latestRenderNodes = null; - var newMarkup = Htmlizer.GetHtml(ComponentId, framesCollection); - - // Volatile write is necessary to ensure the updated markup - // is available across CPU cores. Without it, the pointer to the - // markup string can be stored in a CPUs register and not - // get updated when another CPU changes the string. - Volatile.Write(ref markup, newMarkup); - } + latestRenderNodes = null; + var newMarkup = Htmlizer.GetHtml(ComponentId, framesCollection); + + // Volatile write is necessary to ensure the updated markup + // is available across CPU cores. Without it, the pointer to the + // markup string can be stored in a CPUs register and not + // get updated when another CPU changes the string. + Volatile.Write(ref markup, newMarkup); } - protected virtual void OnRender(RenderEvent renderEvent) { } + /// + /// Extension point for the method. + /// + protected virtual void OnRenderInternal(RenderEvent renderEvent) { } /// /// Ensures that the underlying component behind the @@ -171,5 +175,6 @@ protected virtual void Dispose(bool disposing) IsDisposed = true; markup = string.Empty; OnAfterRender = null; + OnMarkupUpdated = null; } } diff --git a/src/bunit/Rendering/TestRenderer.cs b/src/bunit/Rendering/TestRenderer.cs index 984d7434e..db7bcc508 100644 --- a/src/bunit/Rendering/TestRenderer.cs +++ b/src/bunit/Rendering/TestRenderer.cs @@ -17,7 +17,7 @@ public sealed class TestRenderer : Renderer extern static void CallSetDirectParameters(ComponentState componentState, ParameterView parameters); private readonly object renderTreeUpdateLock = new(); - private readonly Dictionary renderedComponents = new(); + private readonly Dictionary renderedComponents = new(); private readonly List rootComponents = new(); private readonly ILogger logger; private readonly IRenderedComponentActivator activator; @@ -73,11 +73,11 @@ public TestRenderer(IRenderedComponentActivator renderedComponentActivator, Test } /// - public IRenderedFragment RenderFragment(RenderFragment renderFragment) + public RenderedFragment RenderFragment(RenderFragment renderFragment) => Render(renderFragment, id => activator.CreateRenderedFragment(id)); /// - public IRenderedComponent RenderComponent(ComponentParameterCollection parameters) + public RenderedComponent RenderComponent(ComponentParameterCollection parameters) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(parameters); @@ -143,7 +143,7 @@ public IRenderedComponent RenderComponent(ComponentParam } /// - public IRenderedComponent FindComponent(IRenderedFragment parentComponent) + public RenderedComponent FindComponent(RenderedFragment parentComponent) where TComponent : IComponent { var foundComponents = FindComponents(parentComponent, 1); @@ -153,7 +153,7 @@ public IRenderedComponent FindComponent(IRenderedFragmen } /// - public IReadOnlyList> FindComponents(IRenderedFragment parentComponent) + public IReadOnlyList> FindComponents(RenderedFragment parentComponent) where TComponent : IComponent => FindComponents(parentComponent, int.MaxValue); @@ -193,7 +193,7 @@ protected override IComponent ResolveComponentForRenderMode(Type componentType, } /// - internal Task SetDirectParametersAsync(IRenderedFragment renderedComponent, ParameterView parameters) + internal Task SetDirectParametersAsync(RenderedFragment renderedComponent, ParameterView parameters) { ObjectDisposedException.ThrowIf(disposed, this); @@ -401,7 +401,7 @@ protected override void Dispose(bool disposing) } private TResult Render(RenderFragment renderFragment, Func activator) - where TResult : IRenderedFragment + where TResult : RenderedFragment { ObjectDisposedException.ThrowIf(disposed, this); @@ -437,14 +437,14 @@ private TResult Render(RenderFragment renderFragment, Func> FindComponents(IRenderedFragment parentComponent, int resultLimit) + private List> FindComponents(RenderedFragment parentComponent, int resultLimit) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(parentComponent); ObjectDisposedException.ThrowIf(disposed, this); - var result = new List>(); + var result = new List>(); var framesCollection = new RenderTreeFrameDictionary(); // Blocks the renderer from changing the render tree @@ -484,12 +484,12 @@ void FindComponentsInRenderTree(int componentId) } } - private IRenderedComponent GetOrCreateRenderedComponent(RenderTreeFrameDictionary framesCollection, int componentId, TComponent component) + private RenderedComponent GetOrCreateRenderedComponent(RenderTreeFrameDictionary framesCollection, int componentId, TComponent component) where TComponent : IComponent { if (renderedComponents.TryGetValue(componentId, out var renderedComponent)) { - return (IRenderedComponent)renderedComponent; + return (RenderedComponent)renderedComponent; } LoadRenderTreeFrames(componentId, framesCollection); diff --git a/src/bunit/TestContext.cs b/src/bunit/TestContext.cs index 47d492202..0b2eb1363 100644 --- a/src/bunit/TestContext.cs +++ b/src/bunit/TestContext.cs @@ -13,7 +13,7 @@ public class TestContext : IDisposable private TestRenderer? testRenderer; /// - /// Gets or sets the default wait timeout used by "WaitFor" operations, i.e. . + /// Gets or sets the default wait timeout used by "WaitFor" operations, i.e. . /// /// The default is 1 second. public static TimeSpan DefaultWaitTimeout { get; set; } = TimeSpan.FromSeconds(1); @@ -123,7 +123,7 @@ public void DisposeComponents() /// Type of the component to render. /// Parameters to pass to the component when it is rendered. /// The rendered . - public virtual IRenderedComponent RenderComponent(params ComponentParameter[] parameters) + public virtual RenderedComponent RenderComponent(params ComponentParameter[] parameters) where TComponent : IComponent { var renderFragment = new ComponentParameterCollection { parameters } @@ -138,7 +138,7 @@ public virtual IRenderedComponent RenderComponent(params /// Type of the component to render. /// The ComponentParameterBuilder action to add type safe parameters to pass to the component when it is rendered. /// The rendered . - public virtual IRenderedComponent RenderComponent(Action>? parameterBuilder = null) + public virtual RenderedComponent RenderComponent(Action>? parameterBuilder = null) where TComponent : IComponent { var renderFragment = new ComponentParameterCollectionBuilder(parameterBuilder) @@ -156,17 +156,17 @@ public virtual IRenderedComponent RenderComponent(Action /// /// The type of component to find in the render tree. /// The render fragment to render. - /// The . - public virtual IRenderedComponent Render(RenderFragment renderFragment) + /// The . + public virtual RenderedComponent Render(RenderFragment renderFragment) where TComponent : IComponent => this.RenderInsideRenderTree(renderFragment); /// - /// Renders the and returns it as a . + /// Renders the and returns it as a . /// /// The render fragment to render. - /// The . - public virtual IRenderedFragment Render(RenderFragment renderFragment) + /// The . + public virtual RenderedFragment Render(RenderFragment renderFragment) => this.RenderInsideRenderTree(renderFragment); /// diff --git a/src/bunit/TestContextWrapper.cs b/src/bunit/TestContextWrapper.cs index 8afa6b4f8..c8f6757d1 100644 --- a/src/bunit/TestContextWrapper.cs +++ b/src/bunit/TestContextWrapper.cs @@ -43,7 +43,7 @@ public abstract class TestContextWrapper /// Type of the component to render. /// Parameters to pass to the component when it is rendered. /// The rendered . - public virtual IRenderedComponent RenderComponent(params ComponentParameter[] parameters) + public virtual RenderedComponent RenderComponent(params ComponentParameter[] parameters) where TComponent : IComponent => TestContext?.RenderComponent(parameters) ?? throw new InvalidOperationException("The TestContext has not been initialized."); @@ -53,7 +53,7 @@ public virtual IRenderedComponent RenderComponent(params /// Type of the component to render. /// The ComponentParameterBuilder action to add type safe parameters to pass to the component when it is rendered. /// The rendered . - public virtual IRenderedComponent RenderComponent(Action> parameterBuilder) + public virtual RenderedComponent RenderComponent(Action> parameterBuilder) where TComponent : IComponent => TestContext?.RenderComponent(parameterBuilder) ?? throw new InvalidOperationException("The TestContext has not been initialized."); @@ -65,17 +65,17 @@ public virtual IRenderedComponent RenderComponent(Action /// /// The type of component to find in the render tree. /// The render fragment to render. - /// The . - public virtual IRenderedComponent Render(RenderFragment renderFragment) + /// The . + public virtual RenderedComponent Render(RenderFragment renderFragment) where TComponent : IComponent => TestContext?.Render(renderFragment) ?? throw new InvalidOperationException("The TestContext has not been initialized."); /// - /// Renders the and returns it as a . + /// Renders the and returns it as a . /// /// The render fragment to render. - /// The . - public virtual IRenderedFragment Render(RenderFragment renderFragment) + /// The . + public virtual RenderedFragment Render(RenderFragment renderFragment) => TestContext?.Render(renderFragment) ?? throw new InvalidOperationException("The TestContext has not been initialized."); /// diff --git a/tests/bunit.tests/Asserting/CompareToDiffingExtensionsTest.cs b/tests/bunit.tests/Asserting/CompareToDiffingExtensionsTest.cs index 242e3ed4c..e813f10b5 100644 --- a/tests/bunit.tests/Asserting/CompareToDiffingExtensionsTest.cs +++ b/tests/bunit.tests/Asserting/CompareToDiffingExtensionsTest.cs @@ -23,8 +23,8 @@ public static IEnumerable GetCompareToMethods() object p1 = p1Info.ParameterType.ToMockInstance(); object p2 = p2Info.ParameterType.ToMockInstance(); - yield return new object[] { method, p1Info.Name!, new[] { null!, p2! } }; - yield return new object[] { method, p2Info.Name!, new[] { p1!, null! } }; + yield return [method, p1Info.Name!, new[] { null!, p2! }]; + yield return [method, p2Info.Name!, new[] { p1!, null! }]; } } diff --git a/tests/bunit.tests/Asserting/MarkupMatchesAssertExtensionsTest.cs b/tests/bunit.tests/Asserting/MarkupMatchesAssertExtensionsTest.cs index 99d7706af..4b038e676 100644 --- a/tests/bunit.tests/Asserting/MarkupMatchesAssertExtensionsTest.cs +++ b/tests/bunit.tests/Asserting/MarkupMatchesAssertExtensionsTest.cs @@ -8,8 +8,8 @@ public partial class MarkupMatchesAssertExtensionsTest : TestContext private const string ExpectedMarkup = "
BAR
"; private static readonly RenderFragment ActualRenderFragment = b => b.AddMarkupContent(0, ActualMarkup); private static readonly RenderFragment ExpectedRenderFragment = b => b.AddMarkupContent(0, ExpectedMarkup); - private IRenderedFragment ActualRenderedFragment => Render(ActualRenderFragment); - private IRenderedFragment ExpectedRenderedFragment => Render(ExpectedRenderFragment); + private RenderedFragment ActualRenderedFragment => Render(ActualRenderFragment); + private RenderedFragment ExpectedRenderedFragment => Render(ExpectedRenderFragment); private INodeList ActualNodeList => ActualRenderedFragment.Nodes; private INodeList ExpectedNodeList => ExpectedRenderedFragment.Nodes; private INode ActualNode => ActualNodeList[0]; @@ -23,8 +23,8 @@ public void Test001() Should.Throw(() => default(string)!.MarkupMatches(default(string)!)); Should.Throw(() => default(string)!.MarkupMatches(ExpectedRenderedFragment)); - Should.Throw(() => ActualMarkup.MarkupMatches(default(IRenderedFragment)!)); - Should.Throw(() => default(string)!.MarkupMatches(default(IRenderedFragment)!)); + Should.Throw(() => ActualMarkup.MarkupMatches(default(RenderedFragment)!)); + Should.Throw(() => default(string)!.MarkupMatches(default(RenderedFragment)!)); Should.Throw(() => default(string)!.MarkupMatches(ExpectedNodeList)); Should.Throw(() => ActualMarkup.MarkupMatches(default(INodeList)!)); @@ -42,9 +42,9 @@ public void Test001() Should.Throw(() => ActualNode.MarkupMatches(default(INodeList)!)); Should.Throw(() => default(INode)!.MarkupMatches(default(INodeList)!)); - Should.Throw(() => default(IRenderedFragment)!.MarkupMatches(ExpectedRenderFragment)); + Should.Throw(() => default(RenderedFragment)!.MarkupMatches(ExpectedRenderFragment)); Should.Throw(() => ActualRenderedFragment.MarkupMatches(default(RenderFragment)!)); - Should.Throw(() => default(IRenderedFragment)!.MarkupMatches(default(RenderFragment)!)); + Should.Throw(() => default(RenderedFragment)!.MarkupMatches(default(RenderFragment)!)); Should.Throw(() => default(INode)!.MarkupMatches(ExpectedRenderFragment)); Should.Throw(() => ActualNode.MarkupMatches(default(RenderFragment)!)); @@ -59,7 +59,7 @@ public void Test001() public void Test002() => Should.Throw(() => ActualMarkup.MarkupMatches(ExpectedMarkup)); - [Fact(DisplayName = "MarkupMatches(string, IRenderedFragment) correctly diffs markup")] + [Fact(DisplayName = "MarkupMatches(string, RenderedFragment) correctly diffs markup")] public void Test003() => Should.Throw(() => ActualMarkup.MarkupMatches(ExpectedRenderedFragment)); @@ -79,7 +79,7 @@ public void Test006() public void Test007() => Should.Throw(() => ActualNode.MarkupMatches(ExpectedNodeList)); - [Fact(DisplayName = "MarkupMatches(IRenderedFragment, RenderFragment) correctly diffs markup")] + [Fact(DisplayName = "MarkupMatches(RenderedFragment, RenderFragment) correctly diffs markup")] public void Test008() => Should.Throw(() => ActualRenderedFragment.MarkupMatches(ExpectedRenderFragment)); @@ -91,10 +91,10 @@ public void Test009() public void Test0010() => Should.Throw(() => ActualNodeList.MarkupMatches(ExpectedRenderFragment)); - private IRenderedFragment FindAllRenderedFragment => Render(b => b.AddMarkupContent(0, "

test

")); + private RenderedFragment FindAllRenderedFragment => Render(b => b.AddMarkupContent(0, "

test

")); private readonly string findAllExpectedRenderFragment = "

test

"; - [Fact(DisplayName = "MarkupMatches combination works with IRenderedFragment's FindAll extension method")] + [Fact(DisplayName = "MarkupMatches combination works with RenderedFragment's FindAll extension method")] public void Test011() { FindAllRenderedFragment.FindAll("p").MarkupMatches(findAllExpectedRenderFragment); @@ -151,4 +151,4 @@ public void Test016() cut.MarkupMatches(expectedMarkup); } -} \ No newline at end of file +} diff --git a/tests/bunit.tests/ComponentParameterCollectionBuilderTests.cs b/tests/bunit.tests/ComponentParameterCollectionBuilderTests.cs index 77a60513d..bc8f6409f 100644 --- a/tests/bunit.tests/ComponentParameterCollectionBuilderTests.cs +++ b/tests/bunit.tests/ComponentParameterCollectionBuilderTests.cs @@ -37,12 +37,12 @@ private async Task VerifyEventCallbackAsync(string expectedName) EventCallbackCalled.ShouldBeTrue(); } - private IRenderedFragment RenderWithRenderFragment(RenderFragment renderFragment) + private RenderedFragment RenderWithRenderFragment(RenderFragment renderFragment) { return Renderer.RenderFragment(renderFragment); } - private IRenderedComponent RenderWithRenderFragment(RenderFragment renderFragment) + private RenderedComponent RenderWithRenderFragment(RenderFragment renderFragment) where TComponent : IComponent { var res = Renderer.RenderFragment(renderFragment); @@ -695,16 +695,16 @@ public void Test314() action.ShouldNotThrow(); } - + [Fact(DisplayName = "Supplying query string should be reflected in component parameter")] public void Test315() { var navigationManager = Services.GetRequiredService(); var uri = navigationManager.GetUriWithQueryParameter("Query", "Test"); navigationManager.NavigateTo(uri); - + var cut = RenderComponent(); - + cut.Instance.Query.ShouldBe("Test"); } @@ -719,7 +719,7 @@ public void Test316() .ShouldBe(""" To pass a value to a SupplyParameterFromQuery parameter, use the NavigationManager and navigate to the URI. For example: - + var uri = NavigationManager.GetUriWithQueryParameter("Query", "Foo"); NavigationManager.NavigateTo(uri); """); @@ -801,7 +801,7 @@ private sealed class ValidNamesComponent : ComponentBase [Parameter] public Expression> FacialExpressionExpression { get; set; } } #pragma warning restore S1144 // Unused private types or members should be removed - + private sealed class SupplyFromQueryParameterComponent : ComponentBase { [SupplyParameterFromQuery] public string Query { get; set; } diff --git a/tests/bunit.tests/ComponentParameterCollectionTest.cs b/tests/bunit.tests/ComponentParameterCollectionTest.cs index 99b0250b6..b091b364d 100644 --- a/tests/bunit.tests/ComponentParameterCollectionTest.cs +++ b/tests/bunit.tests/ComponentParameterCollectionTest.cs @@ -2,7 +2,7 @@ namespace Bunit; public class ComponentParameterCollectionTest : TestContext { - private IRenderedComponent RenderWithRenderFragment(RenderFragment renderFragment) + private RenderedComponent RenderWithRenderFragment(RenderFragment renderFragment) { var res = Renderer.RenderFragment(renderFragment); return res.FindComponent(); diff --git a/tests/bunit.tests/ComponentParameterFactoryTest.cs b/tests/bunit.tests/ComponentParameterFactoryTest.cs index d3dc660d5..0f7d65adb 100644 --- a/tests/bunit.tests/ComponentParameterFactoryTest.cs +++ b/tests/bunit.tests/ComponentParameterFactoryTest.cs @@ -8,7 +8,7 @@ public class ComponentParameterFactoryTest private const string EXPECTED = nameof(EXPECTED); private static readonly TestContext Context = new(); - private static IRenderedFragment RenderWithRenderFragment(RenderFragment renderFragment) + private static RenderedFragment RenderWithRenderFragment(RenderFragment renderFragment) { return Context.Renderer.RenderFragment(renderFragment); } diff --git a/tests/bunit.tests/EventDispatchExtensions/TriggerEventSpy.cs b/tests/bunit.tests/EventDispatchExtensions/TriggerEventSpy.cs index b8b83b0c5..20473eabd 100644 --- a/tests/bunit.tests/EventDispatchExtensions/TriggerEventSpy.cs +++ b/tests/bunit.tests/EventDispatchExtensions/TriggerEventSpy.cs @@ -5,13 +5,13 @@ namespace Bunit; public class TriggerEventSpy where TEventArgs : EventArgs, new() { - private readonly IRenderedComponent> renderedComponent; + private readonly RenderedComponent> renderedComponent; private readonly string element; private TEventArgs? receivedEvent; public TEventArgs RaisedEvent => receivedEvent!; - public TriggerEventSpy(Func>> componentRenderer, string element, string eventName) + public TriggerEventSpy(Func>> componentRenderer, string element, string eventName) { ArgumentNullException.ThrowIfNull(componentRenderer); diff --git a/tests/bunit.tests/Extensions/InputFile/InputFileTests.cs b/tests/bunit.tests/Extensions/InputFile/InputFileTests.cs index 5aa8f1a30..3fe6b302d 100644 --- a/tests/bunit.tests/Extensions/InputFile/InputFileTests.cs +++ b/tests/bunit.tests/Extensions/InputFile/InputFileTests.cs @@ -60,7 +60,7 @@ public void Test003() [Fact(DisplayName = "UploadFile throws exception when InputFile is null")] public void Test004() { - Action action = () => ((IRenderedComponent)null).UploadFiles(); + Action action = () => ((RenderedComponent)null).UploadFiles(); action.ShouldThrow(); } diff --git a/tests/bunit.tests/Rendering/TestRendererTest.cs b/tests/bunit.tests/Rendering/TestRendererTest.cs index a4e1ecf2f..b9fb6a491 100644 --- a/tests/bunit.tests/Rendering/TestRendererTest.cs +++ b/tests/bunit.tests/Rendering/TestRendererTest.cs @@ -186,7 +186,7 @@ public void Test030() // act var childCuts = sut.FindComponents(cut) - .OfType>() + .OfType>() .ToList(); // assert diff --git a/tests/bunit.tests/TestUtilities/MockingHelpers.cs b/tests/bunit.tests/TestUtilities/MockingHelpers.cs index 2ba25ca7a..399a8c4dd 100644 --- a/tests/bunit.tests/TestUtilities/MockingHelpers.cs +++ b/tests/bunit.tests/TestUtilities/MockingHelpers.cs @@ -1,3 +1,5 @@ +using Bunit.Rendering; + namespace Bunit.TestUtilities; /// @@ -16,6 +18,11 @@ public static class MockingHelpers public static object ToMockInstance(this Type type) { ArgumentNullException.ThrowIfNull(type); + + if (type == typeof(RenderedFragment)) + { + return new RenderedFragmentFake(); + } if (type.IsMockable()) { @@ -45,4 +52,19 @@ public static bool IsMockable(this Type type) /// Gets whether a type is a delegate type. /// public static bool IsDelegateType(this Type type) => type == DelegateType; + + private sealed class RenderedFragmentFake : RenderedFragment + { + public RenderedFragmentFake() : base(0, Fake()) + { + } + + private static IServiceProvider Fake() + { + using var instance = new BunitHtmlParser(); + var fake = Substitute.For(); + fake.GetService(typeof(BunitHtmlParser)).Returns(instance); + return fake; + } + } } From 39c398b68fe782952cb1b8fe2ef5fa089fc9c661 Mon Sep 17 00:00:00 2001 From: Steven Giesel Date: Sun, 3 Mar 2024 11:41:02 +0100 Subject: [PATCH 12/42] refactor: Renamed TestRenderer to BunitRenderer --- .../MarkupMatchesAssertExtensions.cs | 2 +- src/bunit/Diffing/HtmlComparer.cs | 2 +- .../TriggerEventDispatchExtensions.cs | 10 +-- ...tensions.cs => BunitRendererExtensions.cs} | 8 +- .../RenderedFragmentInvokeAsyncExtensions.cs | 8 +- .../WaitForHelpers/WaitForHelper.cs | 2 +- src/bunit/Rendering/BunitHtmlParser.cs | 2 +- .../{TestRenderer.cs => BunitRenderer.cs} | 80 ++++++++++++++----- ...ns.cs => BunitRendererLoggerExtensions.cs} | 18 ++--- src/bunit/Rendering/RenderEvent.cs | 2 +- src/bunit/Rendering/RenderedFragment.cs | 4 +- src/bunit/TestContext.cs | 14 ++-- src/bunit/TestContextWrapper.cs | 2 +- .../BunitPersistentComponentState.cs | 4 +- ...tRendererTest.cs => BunitRendererBunit.cs} | 24 +++++- .../Rendering/TestRendererTest.net5.cs | 24 ------ 16 files changed, 118 insertions(+), 88 deletions(-) rename src/bunit/Extensions/{TestRendererExtensions.cs => BunitRendererExtensions.cs} (89%) rename src/bunit/Rendering/{TestRenderer.cs => BunitRenderer.cs} (79%) rename src/bunit/Rendering/{TestRendererLoggerExtensions.cs => BunitRendererLoggerExtensions.cs} (84%) rename tests/bunit.tests/Rendering/{TestRendererTest.cs => BunitRendererBunit.cs} (95%) delete mode 100644 tests/bunit.tests/Rendering/TestRendererTest.net5.cs diff --git a/src/bunit/Asserting/MarkupMatchesAssertExtensions.cs b/src/bunit/Asserting/MarkupMatchesAssertExtensions.cs index 8f61e9477..4bb3fc51b 100644 --- a/src/bunit/Asserting/MarkupMatchesAssertExtensions.cs +++ b/src/bunit/Asserting/MarkupMatchesAssertExtensions.cs @@ -274,7 +274,7 @@ public static void MarkupMatches(this RenderedFragment actual, RenderFragment ex // TODO: This will be obsolete with: https://github.com/bUnit-dev/bUnit/issues/1018 // As the renderer would be transient we don't have to new up an instance - using var renderer = new TestRenderer( + using var renderer = new BunitRenderer( actual.Services.GetRequiredService(), actual.Services.GetRequiredService(), actual.Services.GetRequiredService()); diff --git a/src/bunit/Diffing/HtmlComparer.cs b/src/bunit/Diffing/HtmlComparer.cs index 2dd73d112..9fc2180bc 100644 --- a/src/bunit/Diffing/HtmlComparer.cs +++ b/src/bunit/Diffing/HtmlComparer.cs @@ -8,7 +8,7 @@ namespace Bunit.Diffing; /// -/// Represents a test HTML comparer, that is configured to work with markup generated by the and classes. +/// Represents a test HTML comparer, that is configured to work with markup generated by the and classes. /// public sealed class HtmlComparer { diff --git a/src/bunit/EventDispatchExtensions/TriggerEventDispatchExtensions.cs b/src/bunit/EventDispatchExtensions/TriggerEventDispatchExtensions.cs index 62e44e9a1..7d75c7f6f 100644 --- a/src/bunit/EventDispatchExtensions/TriggerEventDispatchExtensions.cs +++ b/src/bunit/EventDispatchExtensions/TriggerEventDispatchExtensions.cs @@ -63,7 +63,7 @@ public static Task TriggerEventAsync(this IElement element, string eventName, Ev ArgumentNullException.ThrowIfNull(eventName); var renderer = element.GetTestContext()?.Renderer - ?? throw new InvalidOperationException($"Blazor events can only be raised on elements rendered with the Blazor test renderer '{nameof(TestRenderer)}'."); + ?? throw new InvalidOperationException($"Blazor events can only be raised on elements rendered with the Blazor test renderer '{nameof(BunitRenderer)}'."); // TriggerEventsAsync will traverse the DOM tree to find // all event handlers that needs to be triggered. This is done @@ -78,7 +78,7 @@ public static Task TriggerEventAsync(this IElement element, string eventName, Ev } [SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "HTML events are standardize to lower case and safe in this context.")] - private static Task TriggerEventsAsync(TestRenderer renderer, IElement element, string eventName, EventArgs eventArgs) + private static Task TriggerEventsAsync(BunitRenderer renderer, IElement element, string eventName, EventArgs eventArgs) { var isNonBubblingEvent = NonBubblingEvents.Contains(eventName.ToLowerInvariant()); var unwrappedElement = element.Unwrap(); @@ -88,7 +88,7 @@ private static Task TriggerEventsAsync(TestRenderer renderer, IElement element, : TriggerBubblingEventAsync(renderer, unwrappedElement, eventName, eventArgs); } - private static Task TriggerNonBubblingEventAsync(TestRenderer renderer, IElement element, string eventName, EventArgs eventArgs) + private static Task TriggerNonBubblingEventAsync(BunitRenderer renderer, IElement element, string eventName, EventArgs eventArgs) { var eventAttrName = Htmlizer.ToBlazorAttribute(eventName); @@ -105,7 +105,7 @@ private static Task TriggerNonBubblingEventAsync(TestRenderer renderer, IElement throw new MissingEventHandlerException(element, eventName); } - private static Task TriggerBubblingEventAsync(TestRenderer renderer, IElement element, string eventName, EventArgs eventArgs) + private static Task TriggerBubblingEventAsync(BunitRenderer renderer, IElement element, string eventName, EventArgs eventArgs) { var eventTasks = GetDispatchEventTasks(renderer, element, eventName, eventArgs); @@ -118,7 +118,7 @@ private static Task TriggerBubblingEventAsync(TestRenderer renderer, IElement el } private static List GetDispatchEventTasks( - TestRenderer renderer, + BunitRenderer renderer, IElement element, string eventName, EventArgs eventArgs) diff --git a/src/bunit/Extensions/TestRendererExtensions.cs b/src/bunit/Extensions/BunitRendererExtensions.cs similarity index 89% rename from src/bunit/Extensions/TestRendererExtensions.cs rename to src/bunit/Extensions/BunitRendererExtensions.cs index 31d9817f7..d8c7c097c 100644 --- a/src/bunit/Extensions/TestRendererExtensions.cs +++ b/src/bunit/Extensions/BunitRendererExtensions.cs @@ -3,10 +3,10 @@ namespace Bunit.Extensions; /// -/// Helper methods that make it easier to work directly with a +/// Helper methods that make it easier to work directly with a /// in bUnit web. /// -public static class TestRendererExtensions +public static class BunitRendererExtensions { /// /// Renders a with the parameters passed to it. @@ -15,7 +15,7 @@ public static class TestRendererExtensions /// The renderer to use. /// The parameters to pass to the component. /// A that provides access to the rendered component. - public static RenderedComponent RenderComponent(this TestRenderer renderer, params ComponentParameter[] parameters) + public static RenderedComponent RenderComponent(this BunitRenderer renderer, params ComponentParameter[] parameters) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(renderer); @@ -34,7 +34,7 @@ public static RenderedComponent RenderComponent(this Tes /// The renderer to use. /// The a builder to create parameters to pass to the component. /// A that provides access to the rendered component. - public static RenderedComponent RenderComponent(this TestRenderer renderer, Action> parameterBuilder) + public static RenderedComponent RenderComponent(this BunitRenderer renderer, Action> parameterBuilder) where TComponent : IComponent { ArgumentNullException.ThrowIfNull(renderer); diff --git a/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs b/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs index 232eaa875..cac702a71 100644 --- a/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs +++ b/src/bunit/Extensions/RenderedFragmentInvokeAsyncExtensions.cs @@ -8,7 +8,7 @@ namespace Bunit; public static class RenderedFragmentInvokeAsyncExtensions { /// - /// Invokes the given in the context of the associated . + /// Invokes the given in the context of the associated . /// /// The rendered fragment whose dispatcher to invoke with. /// The work item to execute on the renderer's thread. @@ -26,7 +26,7 @@ public static Task InvokeAsync(this RenderedFragment renderedFragment, Action wo } /// - /// Invokes the given in the context of the associated . + /// Invokes the given in the context of the associated . /// /// The rendered component whose dispatcher to invoke with. /// The work item to execute on the renderer's thread. @@ -44,7 +44,7 @@ public static Task InvokeAsync(this RenderedFragment renderedFragment, Func - /// Invokes the given in the context of the associated . + /// Invokes the given in the context of the associated . /// /// The rendered component whose dispatcher to invoke with. /// The work item to execute on the renderer's thread. @@ -62,7 +62,7 @@ public static Task InvokeAsync(this RenderedFragment renderedFragment, Fun } /// - /// Invokes the given in the context of the associated . + /// Invokes the given in the context of the associated . /// /// The rendered component whose dispatcher to invoke with. /// The work item to execute on the renderer's thread. diff --git a/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs index 41537f974..feee65844 100644 --- a/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs +++ b/src/bunit/Extensions/WaitForHelpers/WaitForHelper.cs @@ -15,7 +15,7 @@ public abstract class WaitForHelper : IDisposable private readonly Func<(bool CheckPassed, T Content)> completeChecker; private readonly RenderedFragment renderedFragment; private readonly ILogger> logger; - private readonly TestRenderer renderer; + private readonly BunitRenderer renderer; private bool isDisposed; private int checkCount; private Exception? capturedException; diff --git a/src/bunit/Rendering/BunitHtmlParser.cs b/src/bunit/Rendering/BunitHtmlParser.cs index c44abab7f..261c8a5ba 100644 --- a/src/bunit/Rendering/BunitHtmlParser.cs +++ b/src/bunit/Rendering/BunitHtmlParser.cs @@ -25,7 +25,7 @@ public sealed class BunitHtmlParser : IDisposable /// /// Initializes a new instance of the class - /// with a AngleSharp context without a registered. + /// with a AngleSharp context without a registered. /// public BunitHtmlParser() : this(Configuration.Default.WithCss().With(new HtmlComparer())) { } diff --git a/src/bunit/Rendering/TestRenderer.cs b/src/bunit/Rendering/BunitRenderer.cs similarity index 79% rename from src/bunit/Rendering/TestRenderer.cs rename to src/bunit/Rendering/BunitRenderer.cs index db7bcc508..c52d0e24a 100644 --- a/src/bunit/Rendering/TestRenderer.cs +++ b/src/bunit/Rendering/BunitRenderer.cs @@ -6,20 +6,20 @@ namespace Bunit.Rendering; /// -/// Represents a bUnit used to render Blazor components and fragments during bUnit tests. +/// Represents a bUnit used to render Blazor components and fragments during bUnit tests. /// -public sealed class TestRenderer : Renderer +public sealed class BunitRenderer : Renderer { [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_isBatchInProgress")] - extern static ref bool GetIsBatchInProgressField(Renderer renderer); + private static extern ref bool GetIsBatchInProgressField(Renderer renderer); [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "SetDirectParameters")] - extern static void CallSetDirectParameters(ComponentState componentState, ParameterView parameters); + private static extern void CallSetDirectParameters(ComponentState componentState, ParameterView parameters); private readonly object renderTreeUpdateLock = new(); private readonly Dictionary renderedComponents = new(); private readonly List rootComponents = new(); - private readonly ILogger logger; + private readonly ILogger logger; private readonly IRenderedComponentActivator activator; private bool disposed; private TaskCompletionSource unhandledExceptionTsc = new(TaskCreationOptions.RunContinuationsAsynchronously); @@ -39,7 +39,10 @@ private bool IsBatchInProgress } } - /// + /// + /// Gets a , which completes when an unhandled exception + /// is thrown during the rendering of a component, that is caught by the renderer. + /// public Task UnhandledException => unhandledExceptionTsc.Task; /// @@ -51,32 +54,41 @@ private bool IsBatchInProgress internal int RenderCount { get; private set; } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - public TestRenderer(IRenderedComponentActivator renderedComponentActivator, TestServiceProvider services, ILoggerFactory loggerFactory) + public BunitRenderer(IRenderedComponentActivator renderedComponentActivator, TestServiceProvider services, ILoggerFactory loggerFactory) : base(services, loggerFactory, new BunitComponentActivator(services.GetRequiredService(), null)) { - logger = loggerFactory.CreateLogger(); + logger = loggerFactory.CreateLogger(); activator = renderedComponentActivator; ElementReferenceContext = new WebElementReferenceContext(services.GetRequiredService()); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - public TestRenderer(IRenderedComponentActivator renderedComponentActivator, TestServiceProvider services, ILoggerFactory loggerFactory, IComponentActivator componentActivator) + public BunitRenderer(IRenderedComponentActivator renderedComponentActivator, TestServiceProvider services, ILoggerFactory loggerFactory, IComponentActivator componentActivator) : base(services, loggerFactory, new BunitComponentActivator(services.GetRequiredService(), componentActivator)) { - logger = loggerFactory.CreateLogger(); + logger = loggerFactory.CreateLogger(); activator = renderedComponentActivator; ElementReferenceContext = new WebElementReferenceContext(services.GetRequiredService()); } - /// + /// + /// Renders the . + /// + /// The to render. + /// A that provides access to the rendered . public RenderedFragment RenderFragment(RenderFragment renderFragment) => Render(renderFragment, id => activator.CreateRenderedFragment(id)); - /// + /// + /// Renders a with the passed to it. + /// + /// The type of component to render. + /// The parameters to pass to the component. + /// A that provides access to the rendered component. public RenderedComponent RenderComponent(ComponentParameterCollection parameters) where TComponent : IComponent { @@ -86,14 +98,26 @@ public RenderedComponent RenderComponent(ComponentParame return Render(renderFragment, id => activator.CreateRenderedComponent(id)); } - /// + /// + /// Notifies the renderer that an event has occurred. + /// + /// The value from the original event attribute. + /// Information that the renderer can use to update the state of the existing render tree to match the UI. + /// Arguments to be passed to the event handler. + /// A which will complete once all asynchronous processing related to the event has completed. public new Task DispatchEventAsync( ulong eventHandlerId, EventFieldInfo fieldInfo, EventArgs eventArgs) => DispatchEventAsync(eventHandlerId, fieldInfo, eventArgs, ignoreUnknownEventHandlers: false); - /// - /// + /// + /// Notifies the renderer that an event has occurred. + /// + /// The value from the original event attribute. + /// Information that the renderer can use to update the state of the existing render tree to match the UI. + /// Arguments to be passed to the event handler. + /// Set to true to ignore the . + /// A which will complete once all asynchronous processing related to the event has completed. public new Task DispatchEventAsync( ulong eventHandlerId, EventFieldInfo fieldInfo, @@ -142,7 +166,11 @@ public RenderedComponent RenderComponent(ComponentParame } } - /// + /// + /// Performs a depth-first search for the first child component of the . + /// + /// Type of component to find. + /// Parent component to search. public RenderedComponent FindComponent(RenderedFragment parentComponent) where TComponent : IComponent { @@ -152,12 +180,18 @@ public RenderedComponent FindComponent(RenderedFragment : throw new ComponentNotFoundException(typeof(TComponent)); } - /// + /// + /// Performs a depth-first search for all child components of the . + /// + /// Type of components to find. + /// Parent component to search. public IReadOnlyList> FindComponents(RenderedFragment parentComponent) where TComponent : IComponent => FindComponents(parentComponent, int.MaxValue); - /// + /// + /// Disposes all components rendered by the . + /// public void DisposeComponents() { ObjectDisposedException.ThrowIf(disposed, this); @@ -225,7 +259,7 @@ internal Task SetDirectParametersAsync(RenderedFragment renderedComponent, Param return result; - static void SetDirectParametersViaComponentState(TestRenderer renderer, int componentId, in ParameterView parameters) + static void SetDirectParametersViaComponentState(BunitRenderer renderer, int componentId, in ParameterView parameters) { var componentState = renderer.GetComponentState(componentId); CallSetDirectParameters(componentState, parameters); @@ -534,8 +568,10 @@ private ArrayRange GetOrLoadRenderTreeFrame(RenderTreeFrameDict } /// - protected override void HandleException([NotNull] Exception exception) + protected override void HandleException(Exception exception) { + ArgumentNullException.ThrowIfNull(exception); + if (disposed) return; diff --git a/src/bunit/Rendering/TestRendererLoggerExtensions.cs b/src/bunit/Rendering/BunitRendererLoggerExtensions.cs similarity index 84% rename from src/bunit/Rendering/TestRendererLoggerExtensions.cs rename to src/bunit/Rendering/BunitRendererLoggerExtensions.cs index 1960677f9..364641309 100644 --- a/src/bunit/Rendering/TestRendererLoggerExtensions.cs +++ b/src/bunit/Rendering/BunitRendererLoggerExtensions.cs @@ -3,7 +3,7 @@ namespace Bunit.Rendering; -internal static class TestRendererLoggerExtensions +internal static class BunitRendererLoggerExtensions { private static readonly Action ComponentDisposed = LoggerMessage.Define( @@ -11,7 +11,7 @@ internal static class TestRendererLoggerExtensions new EventId(11, "ComponentDisposed"), "Component {Id} has been disposed."); - internal static void LogComponentDisposed(this ILogger logger, int componentId) + internal static void LogComponentDisposed(this ILogger logger, int componentId) { if (logger.IsEnabled(LogLevel.Debug)) { @@ -25,7 +25,7 @@ internal static void LogComponentDisposed(this ILogger logger, int new EventId(12, "ComponentRendered"), "Component {ComponentId} has been rendered."); - internal static void LogComponentRendered(this ILogger logger, int componentId) + internal static void LogComponentRendered(this ILogger logger, int componentId) { if (logger.IsEnabled(LogLevel.Debug)) { @@ -39,7 +39,7 @@ internal static void LogComponentRendered(this ILogger logger, int new EventId(14, "DisposedChildInRenderTreeFrame"), "A parent components {ParentComponentId} has a disposed component {ComponentId} as its child."); - internal static void LogDisposedChildInRenderTreeFrame(this ILogger logger, int parentComponentId, int componentId) + internal static void LogDisposedChildInRenderTreeFrame(this ILogger logger, int parentComponentId, int componentId) { if (logger.IsEnabled(LogLevel.Warning)) { @@ -53,7 +53,7 @@ internal static void LogDisposedChildInRenderTreeFrame(this ILogger logger) + internal static void LogAsyncInitialRender(this ILogger logger) { if (logger.IsEnabled(LogLevel.Debug)) { @@ -67,7 +67,7 @@ internal static void LogAsyncInitialRender(this ILogger logger) new EventId(21, "InitialRenderCompleted"), "The initial render of component {ComponentId} is completed."); - internal static void LogInitialRenderCompleted(this ILogger logger, int componentId) + internal static void LogInitialRenderCompleted(this ILogger logger, int componentId) { if (logger.IsEnabled(LogLevel.Debug)) { @@ -81,7 +81,7 @@ private static readonly Action UnhandledExce new EventId(30, "UnhandledException"), "An unhandled exception happened during rendering: {Message}" + Environment.NewLine + "{StackTrace}"); - internal static void LogUnhandledException(this ILogger logger, Exception exception) + internal static void LogUnhandledException(this ILogger logger, Exception exception) { if (logger.IsEnabled(LogLevel.Error)) { @@ -95,7 +95,7 @@ internal static void LogUnhandledException(this ILogger logger, Ex new EventId(31, "RenderCycleActiveAfterDispose"), "A component attempted to update the render tree after the renderer was disposed."); - internal static void LogRenderCycleActiveAfterDispose(this ILogger logger) + internal static void LogRenderCycleActiveAfterDispose(this ILogger logger) { if (logger.IsEnabled(LogLevel.Warning)) { @@ -115,7 +115,7 @@ internal static void LogRenderCycleActiveAfterDispose(this ILogger new EventId(40, "DispatchingEvent"), "Dispatching {EventArgs} to handler (id = {EventHandlerId}) on component {ComponentId}."); - internal static void LogDispatchingEvent(this ILogger logger, ulong eventHandlerId, EventFieldInfo fieldInfo, EventArgs eventArgs) + internal static void LogDispatchingEvent(this ILogger logger, ulong eventHandlerId, EventFieldInfo fieldInfo, EventArgs eventArgs) { if (logger.IsEnabled(LogLevel.Debug)) { diff --git a/src/bunit/Rendering/RenderEvent.cs b/src/bunit/Rendering/RenderEvent.cs index eb88dac4d..e550a4f6f 100644 --- a/src/bunit/Rendering/RenderEvent.cs +++ b/src/bunit/Rendering/RenderEvent.cs @@ -1,7 +1,7 @@ namespace Bunit.Rendering; /// -/// Represents an render event from a . +/// Represents an render event from a . /// public sealed class RenderEvent { diff --git a/src/bunit/Rendering/RenderedFragment.cs b/src/bunit/Rendering/RenderedFragment.cs index 89248a674..dc7efbeb0 100644 --- a/src/bunit/Rendering/RenderedFragment.cs +++ b/src/bunit/Rendering/RenderedFragment.cs @@ -26,7 +26,7 @@ public class RenderedFragment : IDisposable public event EventHandler? OnMarkupUpdated; /// - /// Gets a value indicating whether the rendered component or fragment has been disposed by the . + /// Gets a value indicating whether the rendered component or fragment has been disposed by the . /// public bool IsDisposed { get; private set; } @@ -83,7 +83,7 @@ internal RenderedFragment(int componentId, IServiceProvider service) } /// - /// Called by the owning when it finishes a render. + /// Called by the owning when it finishes a render. /// /// A that represents a render. public void OnRender(RenderEvent renderEvent) diff --git a/src/bunit/TestContext.cs b/src/bunit/TestContext.cs index 0b2eb1363..1a2342214 100644 --- a/src/bunit/TestContext.cs +++ b/src/bunit/TestContext.cs @@ -10,7 +10,7 @@ namespace Bunit; public class TestContext : IDisposable { private bool disposed; - private TestRenderer? testRenderer; + private BunitRenderer? bunitRenderer; /// /// Gets or sets the default wait timeout used by "WaitFor" operations, i.e. . @@ -21,7 +21,7 @@ public class TestContext : IDisposable /// /// Gets the renderer used by the test context. /// - public TestRenderer Renderer => testRenderer ??= CreateTestRenderer(); + public BunitRenderer Renderer => bunitRenderer ??= CreateRenderer(); /// /// Gets bUnits JSInterop, that allows setting up handlers for invocations @@ -91,7 +91,7 @@ protected virtual void Dispose(bool disposing) // Ensure the renderer is disposed before all others, // otherwise a render cycle may be ongoing and try to access // the service provider to perform operations. - if (testRenderer is IDisposable renderer) + if (bunitRenderer is IDisposable renderer) { renderer.Dispose(); } @@ -173,16 +173,16 @@ public virtual RenderedFragment Render(RenderFragment renderFragment) /// Dummy method required to allow Blazor's compiler to generate /// C# from .razor files. /// - protected virtual void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } + protected virtual void BuildRenderTree(RenderTreeBuilder builder) { } - private TestRenderer CreateTestRenderer() + private BunitRenderer CreateRenderer() { var renderedComponentActivator = Services.GetRequiredService(); var logger = Services.GetRequiredService(); var componentActivator = Services.GetService(); return componentActivator is null - ? new TestRenderer(renderedComponentActivator, Services, logger) - : new TestRenderer(renderedComponentActivator, Services, logger, componentActivator); + ? new BunitRenderer(renderedComponentActivator, Services, logger) + : new BunitRenderer(renderedComponentActivator, Services, logger, componentActivator); } } diff --git a/src/bunit/TestContextWrapper.cs b/src/bunit/TestContextWrapper.cs index c8f6757d1..937ef66d6 100644 --- a/src/bunit/TestContextWrapper.cs +++ b/src/bunit/TestContextWrapper.cs @@ -17,7 +17,7 @@ public abstract class TestContextWrapper /// /// Gets the renderer used by the test context. /// - public TestRenderer Renderer => TestContext?.Renderer ?? throw new InvalidOperationException("The TestContext has not been initialized."); + public BunitRenderer Renderer => TestContext?.Renderer ?? throw new InvalidOperationException("The TestContext has not been initialized."); /// /// Gets the service collection and service provider that is used when a diff --git a/src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentState.cs b/src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentState.cs index ae8b12f58..1209e5231 100644 --- a/src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentState.cs +++ b/src/bunit/TestDoubles/PersistentComponentState/BunitPersistentComponentState.cs @@ -17,7 +17,7 @@ public sealed class BunitPersistentComponentState }; private readonly BunitPersistentComponentStateStore store; private readonly Lazy manager; - private readonly Lazy renderer; + private readonly Lazy renderer; /// /// Initializes a new instance of the class. @@ -27,7 +27,7 @@ internal BunitPersistentComponentState(IServiceProvider services) { store = new BunitPersistentComponentStateStore(); manager = new Lazy(() => services.GetRequiredService()); - renderer = new Lazy(() => services.GetRequiredService().Renderer); + renderer = new Lazy(() => services.GetRequiredService().Renderer); } /// diff --git a/tests/bunit.tests/Rendering/TestRendererTest.cs b/tests/bunit.tests/Rendering/BunitRendererBunit.cs similarity index 95% rename from tests/bunit.tests/Rendering/TestRendererTest.cs rename to tests/bunit.tests/Rendering/BunitRendererBunit.cs index b9fb6a491..f28c37e2b 100644 --- a/tests/bunit.tests/Rendering/TestRendererTest.cs +++ b/tests/bunit.tests/Rendering/BunitRendererBunit.cs @@ -5,9 +5,9 @@ namespace Bunit.Rendering; -public partial class TestRendererTest : TestContext +public partial class BunitRendererBunit : TestContext { - public TestRendererTest(ITestOutputHelper outputHelper) + public BunitRendererBunit(ITestOutputHelper outputHelper) { TestContext.DefaultWaitTimeout = TimeSpan.FromSeconds(30); Services.AddXunitLogger(outputHelper); @@ -513,8 +513,26 @@ public void Test211() cut.Find("h1").TextContent.ShouldBe($"Hello world {RenderMode.InteractiveWebAssembly}"); } + + [Fact(DisplayName = "given a IComponentActivator, " + + "when passed to constructor," + + "then it used to create components")] + public void Test1000() + { + var activatorMock = Substitute.For(); + activatorMock.CreateInstance(typeof(Wrapper)).Returns(new Wrapper()); + using var renderer = new BunitRenderer( + Services.GetService(), + Services, + NullLoggerFactory.Instance, + activatorMock); + + renderer.RenderComponent(new ComponentParameterCollection()); + + activatorMock.Received(1).CreateInstance(typeof(Wrapper)); + } - private TestRenderer CreateRenderer() => new TestRenderer( + private BunitRenderer CreateRenderer() => new BunitRenderer( Services.GetRequiredService(), Services, NullLoggerFactory.Instance); diff --git a/tests/bunit.tests/Rendering/TestRendererTest.net5.cs b/tests/bunit.tests/Rendering/TestRendererTest.net5.cs deleted file mode 100644 index 4e1fdb621..000000000 --- a/tests/bunit.tests/Rendering/TestRendererTest.net5.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Microsoft.Extensions.Logging.Abstractions; - -namespace Bunit.Rendering; - -public partial class TestRendererTest : TestContext -{ - [Fact(DisplayName = "given a IComponentActivator, " + - "when passed to constructor," + - "then it used to create components")] - public void Test1000() - { - var activatorMock = Substitute.For(); - activatorMock.CreateInstance(typeof(Wrapper)).Returns(new Wrapper()); - using var renderer = new TestRenderer( - Services.GetService(), - Services, - NullLoggerFactory.Instance, - activatorMock); - - renderer.RenderComponent(new ComponentParameterCollection()); - - activatorMock.Received(1).CreateInstance(typeof(Wrapper)); - } -} From 3b0372a32f373e34a88cfff331ea4a760cea74d1 Mon Sep 17 00:00:00 2001 From: Steven Giesel Date: Sun, 3 Mar 2024 16:57:00 +0100 Subject: [PATCH 13/42] refactor: All rendering methods are surfaced as "Render" --- MIGRATION.md | 3 + bunit.sln | 1 + .../mstest/HelloWorldExplicitContextTest.cs | 2 +- docs/samples/tests/mstest/HelloWorldTest.cs | 2 +- .../nunit/HelloWorldExplicitContextTest.cs | 2 +- .../nunit/HelloWorldInstancePerTestCase.cs | 2 +- docs/samples/tests/nunit/HelloWorldTest.cs | 2 +- .../tests/xunit/AllKindsOfParamsTest.cs | 74 +++++++------- docs/samples/tests/xunit/AsyncDataTest.cs | 6 +- .../tests/xunit/CascadingParams1Test.cs | 2 +- .../tests/xunit/CascadingParams2Test.cs | 2 +- .../tests/xunit/CascadingParams3Test.cs | 2 +- .../tests/xunit/ChildContentParams1Test.cs | 2 +- .../tests/xunit/ChildContentParams2Test.cs | 2 +- .../tests/xunit/ChildContentParams3Test.cs | 2 +- .../tests/xunit/ChildContentParams4Test.cs | 2 +- docs/samples/tests/xunit/ClickMeTest.cs | 2 +- .../xunit/ComponentFactoryExampleTest.cs | 2 +- docs/samples/tests/xunit/CounterTest.cs | 2 +- .../samples/tests/xunit/CounterTestWithCtx.cs | 2 +- .../xunit/CounterWithFancyParagraphTest.cs | 4 +- .../tests/xunit/DisposeComponentsTest.cs | 6 +- .../tests/xunit/EventCallbackParamsTest.cs | 2 +- .../xunit/HelloWorldExplicitContextTest.cs | 2 +- docs/samples/tests/xunit/HelloWorldTest.cs | 2 +- .../tests/xunit/InjectAuthServiceTest.cs | 4 +- .../tests/xunit/NestedComponentTest.cs | 2 +- .../tests/xunit/NonBlazorTypesParamsTest.cs | 2 +- docs/samples/tests/xunit/ReRenderTest.cs | 14 +-- .../tests/xunit/RenderFragmentParams1Test.cs | 2 +- .../tests/xunit/RenderFragmentParams2Test.cs | 2 +- .../tests/xunit/RenderFragmentParams3Test.cs | 2 +- .../tests/xunit/RenderFragmentParams4Test.cs | 2 +- docs/samples/tests/xunit/RenderTreeTest.cs | 4 +- docs/samples/tests/xunit/SemanticHtmlTest.cs | 2 +- .../tests/xunit/TemplateParams1Test.cs | 2 +- .../tests/xunit/TemplateParams2Test.cs | 2 +- docs/samples/tests/xunit/TwoWayBindingTest.cs | 2 +- .../tests/xunit/UnmatchedParamsTest.cs | 2 +- docs/samples/tests/xunit/UserInfoTest.cs | 8 +- docs/samples/tests/xunit/UserRightsTest.cs | 16 +-- .../tests/xunit/VerifyMarkupExamples.cs | 10 +- .../tests/xunit/WeatherForecastsTest.cs | 4 +- .../docs/getting-started/writing-tests.md | 6 +- .../interaction/trigger-event-handlers.md | 2 +- docs/site/docs/interaction/trigger-renders.md | 12 +-- .../passing-parameters-to-components.md | 8 +- .../docs/providing-input/root-render-tree.md | 2 +- .../docs/test-doubles/emulating-ijsruntime.md | 2 +- .../fake-webassemblyhostenvironment.md | 4 +- docs/site/docs/test-doubles/input-file.md | 2 +- .../docs/test-doubles/navigation-manager.md | 8 +- .../test-doubles/persistentcomponentstate.md | 4 +- .../verification/verify-component-state.md | 8 +- .../template/CounterCSharpTests.cs | 4 +- .../ComponentParameterCollectionBuilder.cs | 4 +- .../Extensions/BunitRendererExtensions.cs | 8 +- .../RenderedComponentRenderExtensions.cs | 18 ++-- src/bunit/Rendering/BunitRenderer.cs | 2 +- src/bunit/TestContext.cs | 6 +- src/bunit/TestContextWrapper.cs | 8 +- .../Web.Stub/AddStubGeneratorTests.cs | 4 +- .../CompareToDiffingExtensionsTest.cs | 16 +-- .../MarkupMatchesAssertExtensionsTest.cs | 10 +- .../MarkupMatchesAssertExtensionsTest.net5.cs | 2 +- .../BlazorE2E/ComponentRenderingTest.cs | 96 +++++++++--------- .../ConditionalComponentFactoryTest.cs | 6 +- .../GenericComponentFactoryTest.cs | 2 +- .../InstanceComponentFactoryTest.cs | 6 +- .../StubComponentFactoryTest.cs | 18 ++-- .../TypeBasedComponentFactoryTest.cs | 4 +- ...omponentParameterCollectionBuilderTests.cs | 4 +- ...onentParameterCollectionBuilderTests.razor | 2 +- ...ilsElementEventDispatcherExtensionsTest.cs | 2 +- .../EventDispatchExtensionsTest.cs | 4 +- .../GeneralEventDispatchExtensionsTest.cs | 42 ++++---- .../InputEventDispatchExtensionsTest.cs | 4 +- .../Extensions/InputFile/InputFileTests.cs | 10 +- .../RefreshableQueryCollectionTest.cs | 10 +- .../RefreshingWrappedElementTest.cs | 14 +-- .../RenderedComponentRenderExtensionsTest.cs | 6 +- ...tForElementsHelperExtensions.Async.Test.cs | 14 +-- ...mentWaitForElementsHelperExtensionsTest.cs | 14 +-- ...eredFragmentWaitForHelperExtensionsTest.cs | 16 +-- .../FocusAsyncInvocationHandlerTest.cs | 6 +- .../FocusOnNavigateHandlerTest.cs | 4 +- ...irtualizeJSRuntimeInvocationHandlerTest.cs | 12 +-- .../Rendering/BunitComponentActivatorTest.cs | 6 +- .../Rendering/BunitRendererBunit.cs | 97 +++++++------------ .../Rendering/Internal/HtmlizerTests.cs | 8 +- .../Rendering/RenderedComponentTest.cs | 26 ++--- .../Rendering/RenderedFragmentTest.cs | 28 +++--- .../Rendering/RootRenderTreeTest.cs | 20 ++-- tests/bunit.tests/TestContextTest.cs | 44 ++++----- .../Authorization/AuthorizationTest.cs | 38 ++++---- .../BunitSignOutSessionStateManagerTest.cs | 2 +- .../BunitWebAssemblyHostEnvironmentTest.cs | 4 +- .../Components/ComponentDoubleBaseTest.cs | 2 +- .../TestDoubles/Components/StubTest.cs | 4 +- .../BunitNavigationManagerTest.cs | 8 +- .../BunitPersistentComponentStateTest.cs | 4 +- tests/bunit.tests/TestServiceProviderTest.cs | 8 +- 102 files changed, 461 insertions(+), 488 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 29339e908..d9726ca1c 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -42,3 +42,6 @@ The `AddTestAuthorization` method on `TestContext` has been renamed to `AddAutho ## Merged `TestContext` and `TestContextBase` The `TestContext` and `TestContextBase` classes have been merged into a single `TestContext` class. All references to `TestContextBase` should replace them with `TestContext` to migrate. + +## Renamed all `RenderComponent` and `SetParametersAndRender` to `Render` +To make the API more consistent, `RenderComponent` and `SetParametersAndRender` methods have been renamed to `Render`. diff --git a/bunit.sln b/bunit.sln index 117ccb6ea..9a284fd0b 100644 --- a/bunit.sln +++ b/bunit.sln @@ -69,6 +69,7 @@ Global {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Release|Any CPU.ActiveCfg = Release|Any CPU {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Release|Any CPU.Build.0 = Release|Any CPU + {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Debug|Any CPU.Build.0 = Debug|Any CPU {6127D121-9387-451B-B15D-8350A32D3001}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6127D121-9387-451B-B15D-8350A32D3001}.Release|Any CPU.ActiveCfg = Release|Any CPU {7972A80F-30DC-4EF4-9294-7D4DD2965882}.Debug|Any CPU.ActiveCfg = Debug|Any CPU diff --git a/docs/samples/tests/mstest/HelloWorldExplicitContextTest.cs b/docs/samples/tests/mstest/HelloWorldExplicitContextTest.cs index 32734e2fe..a4b7942af 100644 --- a/docs/samples/tests/mstest/HelloWorldExplicitContextTest.cs +++ b/docs/samples/tests/mstest/HelloWorldExplicitContextTest.cs @@ -13,7 +13,7 @@ public void HelloWorldComponentRendersCorrectly() using var ctx = new Bunit.TestContext(); // Act - var cut = ctx.RenderComponent(); + var cut = ctx.Render(); // Assert cut.MarkupMatches("

Hello world from Blazor

"); diff --git a/docs/samples/tests/mstest/HelloWorldTest.cs b/docs/samples/tests/mstest/HelloWorldTest.cs index 13c8f69c7..a83afd638 100644 --- a/docs/samples/tests/mstest/HelloWorldTest.cs +++ b/docs/samples/tests/mstest/HelloWorldTest.cs @@ -10,7 +10,7 @@ public class HelloWorldTest : BunitTestContext public void HelloWorldComponentRendersCorrectly() { // Act - var cut = RenderComponent(); + var cut = Render(); // Assert cut.MarkupMatches("

Hello world from Blazor

"); diff --git a/docs/samples/tests/nunit/HelloWorldExplicitContextTest.cs b/docs/samples/tests/nunit/HelloWorldExplicitContextTest.cs index a35a15f7d..6727db19d 100644 --- a/docs/samples/tests/nunit/HelloWorldExplicitContextTest.cs +++ b/docs/samples/tests/nunit/HelloWorldExplicitContextTest.cs @@ -12,7 +12,7 @@ public void HelloWorldComponentRendersCorrectly() using var ctx = new Bunit.TestContext(); // Act - var cut = ctx.RenderComponent(); + var cut = ctx.Render(); // Assert cut.MarkupMatches("

Hello world from Blazor

"); diff --git a/docs/samples/tests/nunit/HelloWorldInstancePerTestCase.cs b/docs/samples/tests/nunit/HelloWorldInstancePerTestCase.cs index 95f6edd23..b5d7142be 100644 --- a/docs/samples/tests/nunit/HelloWorldInstancePerTestCase.cs +++ b/docs/samples/tests/nunit/HelloWorldInstancePerTestCase.cs @@ -9,7 +9,7 @@ public class HelloWorldInstancePerTestCase : Bunit.TestContext public void HelloWorldComponentRendersCorrectly() { // Act - var cut = RenderComponent(); + var cut = Render(); // Assert cut.MarkupMatches("

Hello world from Blazor

"); diff --git a/docs/samples/tests/nunit/HelloWorldTest.cs b/docs/samples/tests/nunit/HelloWorldTest.cs index d8ad7011d..cce56a764 100644 --- a/docs/samples/tests/nunit/HelloWorldTest.cs +++ b/docs/samples/tests/nunit/HelloWorldTest.cs @@ -9,7 +9,7 @@ public class HelloWorldTest : BunitTestContext public void HelloWorldComponentRendersCorrectly() { // Act - var cut = RenderComponent(); + var cut = Render(); // Assert cut.MarkupMatches("

Hello world from Blazor

"); diff --git a/docs/samples/tests/xunit/AllKindsOfParamsTest.cs b/docs/samples/tests/xunit/AllKindsOfParamsTest.cs index 13179ddc5..18c4fec4d 100644 --- a/docs/samples/tests/xunit/AllKindsOfParamsTest.cs +++ b/docs/samples/tests/xunit/AllKindsOfParamsTest.cs @@ -14,25 +14,25 @@ public class AllKindsOfParamsTest : TestContext public void NonBlazorParamTypes() { // Using C# tuple with hardcoded name - var cut1 = RenderComponent( + var cut1 = Render( ("Numbers", 42), ("Lines", new List { "Hello", "World" }) ); // Using C# tuple with refactor safe name - var cut2 = RenderComponent( + var cut2 = Render( (nameof(NonBlazorTypesParams.Numbers), 42), (nameof(NonBlazorTypesParams.Lines), new List { "Hello", "World" }) ); // Using factory method - var cut3 = RenderComponent( + var cut3 = Render( Parameter("Numbers", 42), Parameter("Lines", new List { "Hello", "World" }) ); // Using parameter builder - var cut4 = RenderComponent(parameters => parameters + var cut4 = Render(parameters => parameters .Add(p => p.Numbers, 42) .Add(p => p.Lines, new List { "Hello", "World" }) ); @@ -43,7 +43,7 @@ public void EventCallbackTypes() { // Using factory method with hardcoded name - var cut1 = RenderComponent( + var cut1 = Render( EventCallback("OnClick", (MouseEventArgs args) => { /* handle callback */ @@ -55,7 +55,7 @@ public void EventCallbackTypes() ); // Using factory method refactor safe name - var cut2 = RenderComponent( + var cut2 = Render( EventCallback(nameof(EventCallbackParams.OnClick), (MouseEventArgs args) => { /* handle callback */ @@ -67,7 +67,7 @@ public void EventCallbackTypes() ); // Using parameter builder - var cut3 = RenderComponent(parameters => parameters + var cut3 = Render(parameters => parameters .Add(p => p.OnClick, args => { /* handle callback */ @@ -83,12 +83,12 @@ public void EventCallbackTypes() public void HtmlAsChildContent() { // Using factory method - var cut1 = RenderComponent( + var cut1 = Render( ChildContent("

Hello World

") ); // Using parameter builder - var cut2 = RenderComponent(parameters => parameters + var cut2 = Render(parameters => parameters .AddChildContent("

Hello World

") ); } @@ -97,12 +97,12 @@ public void HtmlAsChildContent() public void ComponentAsChildContent() { // Using factory method - var cut1 = RenderComponent( + var cut1 = Render( ChildContent() ); // Using parameter builder - var cut2 = RenderComponent(parameters => parameters + var cut2 = Render(parameters => parameters .AddChildContent() ); } @@ -111,7 +111,7 @@ public void ComponentAsChildContent() public void ComponentWithParamsAsChildContent() { // Using factory method - var cut1 = RenderComponent( + var cut1 = Render( ChildContent( ("Heading", "Alert heading"), ("Type", AlertType.Warning), @@ -120,7 +120,7 @@ public void ComponentWithParamsAsChildContent() ); // Using parameter builder - var cut2 = RenderComponent(parameters => parameters + var cut2 = Render(parameters => parameters .AddChildContent(alertParameters => alertParameters .Add(p => p.Heading, "Alert heading") .Add(p => p.Type, AlertType.Warning) @@ -133,7 +133,7 @@ public void ComponentWithParamsAsChildContent() public void ComponentAndMarkupAsChildContent() { // Using factory method - var cut1 = RenderComponent( + var cut1 = Render( ChildContent("

Below you will find a most interesting alert!

"), ChildContent( ("Heading", "Alert heading"), @@ -143,7 +143,7 @@ public void ComponentAndMarkupAsChildContent() ); // Using parameter builder - var cut2 = RenderComponent(parameters => parameters + var cut2 = Render(parameters => parameters .AddChildContent("

Below you will find a most interesting alert!

") .AddChildContent(childParams => childParams .Add(p => p.Heading, "Alert heading") @@ -157,12 +157,12 @@ public void ComponentAndMarkupAsChildContent() public void HtmlAsRenderFragment() { // Using factory method - var cut1 = RenderComponent( + var cut1 = Render( RenderFragment("Content", "

Hello World

") ); // Using parameter builder - var cut2 = RenderComponent(parameters => parameters + var cut2 = Render(parameters => parameters .Add(p => p.Content, "

Hello World

") ); } @@ -171,12 +171,12 @@ public void HtmlAsRenderFragment() public void ComponentAsRenderFragment() { // Using factory method - var cut1 = RenderComponent( + var cut1 = Render( RenderFragment("Content") ); // Using parameter builder - var cut2 = RenderComponent(parameters => parameters + var cut2 = Render(parameters => parameters .Add(p => p.Content) ); } @@ -185,7 +185,7 @@ public void ComponentAsRenderFragment() public void ComponentWithParamsAsRenderFragment() { // Using factory method - var cut1 = RenderComponent( + var cut1 = Render( RenderFragment("Content", ("Heading", "Alert heading"), ("Type", AlertType.Warning), @@ -194,7 +194,7 @@ public void ComponentWithParamsAsRenderFragment() ); // Using parameter builder - var cut2 = RenderComponent(parameters => parameters + var cut2 = Render(parameters => parameters .Add(p => p.Content, alertParameters => alertParameters .Add(p => p.Heading, "Alert heading") .Add(p => p.Type, AlertType.Warning) @@ -207,7 +207,7 @@ public void ComponentWithParamsAsRenderFragment() public void ComponentAndMarkupAsRenderFragment() { // Using factory method - var cut1 = RenderComponent( + var cut1 = Render( RenderFragment("Content", "

Below you will find a most interesting alert!

"), RenderFragment("Content", ("Heading", "Alert heading"), @@ -217,7 +217,7 @@ public void ComponentAndMarkupAsRenderFragment() ); // Using parameter builder - var cut2 = RenderComponent(parameters => parameters + var cut2 = Render(parameters => parameters .Add(p => p.Content, "

Below you will find a most interesting alert!

") .Add(p => p.Content, childParams => childParams .Add(p => p.Heading, "Alert heading") @@ -231,13 +231,13 @@ public void ComponentAndMarkupAsRenderFragment() public void HtmlTemplateParams() { // Using factory method - var cut1 = RenderComponent>( + var cut1 = Render>( ("Items", new string[] { "Foo", "Bar", "Baz" }), Template("Template", item => $"{item}") ); // Using parameter builder - var cut2 = RenderComponent>(parameters => parameters + var cut2 = Render>(parameters => parameters .Add(p => p.Items, new[] { "Foo", "Bar", "Baz" }) .Add(p => p.Template, item => $"{item}") ); @@ -247,7 +247,7 @@ public void HtmlTemplateParams() public void HtmlAndComponentTemplateParams() { // Using factory method - var cut1 = RenderComponent>( + var cut1 = Render>( ("Items", new string[] { "Foo", "Bar", "Baz" }), Template("Template", value => new ComponentParameter[] { @@ -256,7 +256,7 @@ public void HtmlAndComponentTemplateParams() ); // Using parameter builder - var cut2 = RenderComponent>(parameters => parameters + var cut2 = Render>(parameters => parameters .Add(p => p.Items, new[] { "Foo", "Bar", "Baz" }) .Add(p => p.Template, value => itemParams => itemParams .Add(p => p.Value, value) @@ -268,12 +268,12 @@ public void HtmlAndComponentTemplateParams() public void UnmatchedParamsTest() { // Using factory method - var cut1 = RenderComponent( + var cut1 = Render( ("some-unknown-param", "a value") ); // Using parameter builder - var cut2 = RenderComponent(parameters => parameters + var cut2 = Render(parameters => parameters .AddUnmatched("some-unknown-param", "a value") ); } @@ -284,17 +284,17 @@ public void UnnamedCascadingParamsTest() var isDarkTheme = true; // Using factory method - var cut1 = RenderComponent( + var cut1 = Render( CascadingValue(isDarkTheme) ); // Using parameter builder - var cut2 = RenderComponent(parameters => parameters + var cut2 = Render(parameters => parameters .AddCascadingValue(isDarkTheme) ); // Using parameter builder and selecting unnamed cascading parameter - var cut3 = RenderComponent(parameters => parameters + var cut3 = Render(parameters => parameters .Add(p => p.IsDarkTheme, isDarkTheme) ); } @@ -303,12 +303,12 @@ public void UnnamedCascadingParamsTest() public void NamedCascadingParamsTest() { // Using factory method - var cut1 = RenderComponent( + var cut1 = Render( CascadingValue("LoggedInUser", "Egil Hansen") ); // Using parameter builder - var cut2 = RenderComponent(parameters => parameters + var cut2 = Render(parameters => parameters .Add(p => p.UserName, "Egil Hansen") ); } @@ -319,21 +319,21 @@ public void UnnamedAndNamedCascadingParamsTest() var isDarkTheme = true; // Using factory method - var cut1 = RenderComponent( + var cut1 = Render( CascadingValue(isDarkTheme), CascadingValue("LoggedInUser", "Egil Hansen"), CascadingValue("LoggedInEmail", "egil@example.com") ); // Using parameter builder - var cut2 = RenderComponent(parameters => parameters + var cut2 = Render(parameters => parameters .AddCascadingValue(isDarkTheme) .Add(p => p.UserName, "Egil Hansen") .Add(p => p.Email, "egil@example.com") ); // Using parameter builder and selecting unnamed cascading parameter - var cut3 = RenderComponent(parameters => parameters + var cut3 = Render(parameters => parameters .Add(p => p.IsDarkTheme, isDarkTheme) .Add(p => p.UserName, "Egil Hansen") .Add(p => p.Email, "egil@example.com") diff --git a/docs/samples/tests/xunit/AsyncDataTest.cs b/docs/samples/tests/xunit/AsyncDataTest.cs index edb90e0cc..9731faf40 100644 --- a/docs/samples/tests/xunit/AsyncDataTest.cs +++ b/docs/samples/tests/xunit/AsyncDataTest.cs @@ -13,7 +13,7 @@ public void LoadDataAsync() { // Arrange var textService = new TaskCompletionSource(); - var cut = RenderComponent(parameters => parameters + var cut = Render(parameters => parameters .Add(p => p.TextService, textService.Task) ); @@ -32,7 +32,7 @@ public void LoadDataAsyncWithTimeout() { // Arrange var textService = new TaskCompletionSource(); - var cut = RenderComponent(parameters => parameters + var cut = Render(parameters => parameters .Add(p => p.TextService, textService.Task) ); @@ -51,7 +51,7 @@ public void LoadDataAsyncAssertion() { // Arrange var textService = new TaskCompletionSource(); - var cut = RenderComponent(parameters => parameters + var cut = Render(parameters => parameters .Add(p => p.TextService, textService.Task) ); diff --git a/docs/samples/tests/xunit/CascadingParams1Test.cs b/docs/samples/tests/xunit/CascadingParams1Test.cs index a6816f45c..9bb71cd97 100644 --- a/docs/samples/tests/xunit/CascadingParams1Test.cs +++ b/docs/samples/tests/xunit/CascadingParams1Test.cs @@ -15,7 +15,7 @@ public void Test() { var isDarkTheme = true; - var cut = RenderComponent(parameters => parameters + var cut = Render(parameters => parameters .Add(p => p.IsDarkTheme, isDarkTheme) ); } diff --git a/docs/samples/tests/xunit/CascadingParams2Test.cs b/docs/samples/tests/xunit/CascadingParams2Test.cs index 2d72965e8..193e593fa 100644 --- a/docs/samples/tests/xunit/CascadingParams2Test.cs +++ b/docs/samples/tests/xunit/CascadingParams2Test.cs @@ -13,7 +13,7 @@ public class CascadingParams2Test : TestContext [Fact] public void Test() { - var cut = RenderComponent(parameters => parameters + var cut = Render(parameters => parameters .Add(p => p.UserName, "Name of User") ); } diff --git a/docs/samples/tests/xunit/CascadingParams3Test.cs b/docs/samples/tests/xunit/CascadingParams3Test.cs index 23e736fff..0a6e49d26 100644 --- a/docs/samples/tests/xunit/CascadingParams3Test.cs +++ b/docs/samples/tests/xunit/CascadingParams3Test.cs @@ -15,7 +15,7 @@ public void Test() { var isDarkTheme = true; - var cut = RenderComponent(parameters => parameters + var cut = Render(parameters => parameters .Add(p => p.IsDarkTheme, isDarkTheme) .Add(p => p.UserName, "Name of User") .Add(p => p.Email, "user@example.com") diff --git a/docs/samples/tests/xunit/ChildContentParams1Test.cs b/docs/samples/tests/xunit/ChildContentParams1Test.cs index 87299ec7b..b480642da 100644 --- a/docs/samples/tests/xunit/ChildContentParams1Test.cs +++ b/docs/samples/tests/xunit/ChildContentParams1Test.cs @@ -13,7 +13,7 @@ public class ChildContentParams1Test : TestContext [Fact] public void Test() { - var cut = RenderComponent(parameters => parameters + var cut = Render(parameters => parameters .AddChildContent("

Hello World

") ); } diff --git a/docs/samples/tests/xunit/ChildContentParams2Test.cs b/docs/samples/tests/xunit/ChildContentParams2Test.cs index cc2e57c74..8c0c2b4f9 100644 --- a/docs/samples/tests/xunit/ChildContentParams2Test.cs +++ b/docs/samples/tests/xunit/ChildContentParams2Test.cs @@ -13,7 +13,7 @@ public class ChildContentParams2Test : TestContext [Fact] public void Test() { - var cut = RenderComponent(parameters => parameters + var cut = Render(parameters => parameters .AddChildContent() ); } diff --git a/docs/samples/tests/xunit/ChildContentParams3Test.cs b/docs/samples/tests/xunit/ChildContentParams3Test.cs index 58aaa4d98..880c4442a 100644 --- a/docs/samples/tests/xunit/ChildContentParams3Test.cs +++ b/docs/samples/tests/xunit/ChildContentParams3Test.cs @@ -13,7 +13,7 @@ public class ChildContentParams3Test : TestContext [Fact] public void Test() { - var cut = RenderComponent(parameters => parameters + var cut = Render(parameters => parameters .AddChildContent(alertParameters => alertParameters .Add(p => p.Heading, "Alert heading") .Add(p => p.Type, AlertType.Warning) diff --git a/docs/samples/tests/xunit/ChildContentParams4Test.cs b/docs/samples/tests/xunit/ChildContentParams4Test.cs index cbbf4e0b6..54388d9e5 100644 --- a/docs/samples/tests/xunit/ChildContentParams4Test.cs +++ b/docs/samples/tests/xunit/ChildContentParams4Test.cs @@ -13,7 +13,7 @@ public class ChildContentParams4Test : TestContext [Fact] public void Test() { - var cut = RenderComponent(parameters => parameters + var cut = Render(parameters => parameters .AddChildContent("

Below you will find a most interesting alert!

") .AddChildContent(childParams => childParams .Add(p => p.Heading, "Alert heading") diff --git a/docs/samples/tests/xunit/ClickMeTest.cs b/docs/samples/tests/xunit/ClickMeTest.cs index 4e6a2186e..6c14410a6 100644 --- a/docs/samples/tests/xunit/ClickMeTest.cs +++ b/docs/samples/tests/xunit/ClickMeTest.cs @@ -10,7 +10,7 @@ public class ClickMeTest : TestContext public void Test() { // Arrange - var cut = RenderComponent(); + var cut = Render(); var buttonElement = cut.Find("button"); // Act diff --git a/docs/samples/tests/xunit/ComponentFactoryExampleTest.cs b/docs/samples/tests/xunit/ComponentFactoryExampleTest.cs index f11a8c898..47893e27b 100644 --- a/docs/samples/tests/xunit/ComponentFactoryExampleTest.cs +++ b/docs/samples/tests/xunit/ComponentFactoryExampleTest.cs @@ -13,7 +13,7 @@ public void ReplacesFooWithBarDuringTest() ComponentFactories.Add(new FooBarComponentFactory()); // Act - var cut = RenderComponent(parameters => parameters + var cut = Render(parameters => parameters .AddChildContent()); // Assert that there are no in render tree, diff --git a/docs/samples/tests/xunit/CounterTest.cs b/docs/samples/tests/xunit/CounterTest.cs index 366a3f5f4..7f44ad736 100644 --- a/docs/samples/tests/xunit/CounterTest.cs +++ b/docs/samples/tests/xunit/CounterTest.cs @@ -9,7 +9,7 @@ public class CounterTest : TestContext public void CounterShouldIncrementWhenClicked() { // Arrange: render the Counter.razor component - var cut = RenderComponent(); + var cut = Render(); // Act: find and click the