Skip to content

Commit 968a632

Browse files
committed
Deprecated Fixture.Test and Fixture.Tests methods
1 parent 1112627 commit 968a632

22 files changed

Lines changed: 420 additions & 466 deletions

src/bunit.core.tests/ComponentParameterBuilderTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,12 +385,12 @@ public void Test104()
385385
Assert.Throws<ArgumentException>(() => sut.Add(c => c.DummyMethod(), 42));
386386
}
387387

388-
private ComponentParameterBuilder<AllTypesOfParams<string>> CreateSut()
388+
private static ComponentParameterBuilder<AllTypesOfParams<string>> CreateSut()
389389
{
390390
return CreateSut<AllTypesOfParams<string>>();
391391
}
392392

393-
private ComponentParameterBuilder<TComponent> CreateSut<TComponent>() where TComponent : class, IComponent
393+
private static ComponentParameterBuilder<TComponent> CreateSut<TComponent>() where TComponent : class, IComponent
394394
{
395395
return new ComponentParameterBuilder<TComponent>();
396396
}

src/bunit.core/RazorTesting/FixtureBase.cs

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,59 +14,51 @@ namespace Bunit.RazorTesting
1414
/// </summary>
1515
public abstract class FixtureBase<TFixture> : RazorTestBase
1616
{
17+
/// <inheritdoc/>
18+
public override string? DisplayName => Description ?? Test?.Method.Name ?? TestAsync?.Method.Name;
19+
1720
/// <summary>
1821
/// Gets or sets the child content of the fragment.
1922
/// </summary>
2023
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
2124

2225
/// <summary>
23-
/// Gets or sets the setup action to perform before the <see cref="Test"/> action,
24-
/// <see cref="TestAsync"/> action and <see cref="Tests"/> and <see cref="TestsAsync"/> actions are invoked.
26+
/// Gets or sets the setup action to perform before the <see cref="Test"/> action or
27+
/// <see cref="TestAsync"/> action are invoked.
2528
/// </summary>
2629
[Parameter] public Action<TFixture>? Setup { get; set; }
2730

2831
/// <summary>
29-
/// Gets or sets the asynchronous setup action to perform before the <see cref="Test"/> action,
30-
/// <see cref="TestAsync"/> action and <see cref="Tests"/> and <see cref="TestsAsync"/> actions are invoked.
32+
/// Gets or sets the asynchronous setup action to perform before the <see cref="Test"/> action or
33+
/// <see cref="TestAsync"/> action are invoked.
3134
/// </summary>
3235
[Parameter] public Func<TFixture, Task>? SetupAsync { get; set; }
3336

3437
/// <summary>
35-
/// Gets or sets the first test action to invoke, after the <see cref="Setup"/> action has
36-
/// executed (if provided).
37-
///
38-
/// Use this to assert against the <see cref="ComponentUnderTest"/> and <see cref="Fragment"/>'s
39-
/// defined in the fixture.
38+
/// Gets or sets the test action to invoke, after the <see cref="Setup"/> and <see cref="SetupAsync"/> actions has
39+
/// invoked (if provided).
40+
/// If this is set, then <see cref="TestAsync"/> cannot also be set.
4041
/// </summary>
4142
[Parameter] public Action<TFixture>? Test { get; set; }
4243

4344
/// <summary>
44-
/// Gets or sets the first test action to invoke, after the <see cref="SetupAsync"/> action has
45-
/// executed (if provided).
46-
///
47-
/// Use this to assert against the <see cref="ComponentUnderTest"/> and <see cref="Fragment"/>'s
48-
/// defined in the fixture.
45+
/// Gets or sets the test action to invoke, after the <see cref="Setup"/> and <see cref="SetupAsync"/> actions has
46+
/// invoked (if provided).
47+
/// If this is set, then <see cref="Test"/> cannot also be set.
4948
/// </summary>
5049
[Parameter] public Func<TFixture, Task>? TestAsync { get; set; }
5150

5251
/// <summary>
53-
/// Gets or sets the test actions to invoke, one at the time, in the order they are placed
54-
/// into the collection, after the <see cref="Setup"/> action and the <see cref="Test"/> action has
55-
/// executed (if provided).
56-
///
57-
/// Use this to assert against the <see cref="ComponentUnderTest"/> and <see cref="Fragment"/>'s
58-
/// defined in the fixture.
52+
/// Obsolete. Methods assigned to this parameter will not be invoked.
5953
/// </summary>
60-
[Parameter] public IReadOnlyCollection<Action<TFixture>>? Tests { get; set; }
54+
[Obsolete("This feature has been removed since it caused confusion about the state of the fixture being passed to the test methods. Methods assigned to this parameter will not be invoked.")]
55+
[Parameter]
56+
public IReadOnlyCollection<Action<TFixture>>? Tests { get; set; }
6157

6258
/// <summary>
63-
/// Gets or sets the test actions to invoke, one at the time, in the order they are placed
64-
/// into the collection, after the <see cref="SetupAsync"/> action and the <see cref="TestAsync"/> action has
65-
/// executed (if provided).
66-
///
67-
/// Use this to assert against the <see cref="ComponentUnderTest"/> and <see cref="Fragment"/>'s
68-
/// defined in the fixture.
59+
/// Obsolete. Methods assigned to this parameter will not be invoked.
6960
/// </summary>
61+
[Obsolete("This feature has been removed since it caused confusion about the state of the fixture being passed to the test methods. Methods assigned to this parameter will not be invoked.")]
7062
[Parameter]
7163
public IReadOnlyCollection<Func<TFixture, Task>>? TestsAsync { get; set; }
7264

@@ -78,8 +70,13 @@ public override Task SetParametersAsync(ParameterView parameters)
7870
SetupAsync = parameters.GetValueOrDefault<Func<TFixture, Task>>(nameof(SetupAsync));
7971
Test = parameters.GetValueOrDefault<Action<TFixture>>(nameof(Test));
8072
TestAsync = parameters.GetValueOrDefault<Func<TFixture, Task>>(nameof(TestAsync));
81-
Tests = parameters.GetValueOrDefault<IReadOnlyCollection<Action<TFixture>>>(nameof(Tests), Array.Empty<Action<TFixture>>());
82-
TestsAsync = parameters.GetValueOrDefault<IReadOnlyCollection<Func<TFixture, Task>>>(nameof(TestsAsync), Array.Empty<Func<TFixture, Task>>());
73+
74+
#pragma warning disable CS0618 // Type or member is obsolete
75+
if (parameters.TryGetValue<IReadOnlyCollection<Action<TFixture>>>("Tests", out var tests))
76+
Tests = tests;
77+
if (parameters.TryGetValue<IReadOnlyCollection<Func<TFixture, Task>>>("TestsAsync", out var asyncTests))
78+
TestsAsync = asyncTests;
79+
#pragma warning restore CS0618 // Type or member is obsolete
8380

8481
return base.SetParametersAsync(parameters);
8582
}
@@ -90,8 +87,16 @@ public override void Validate()
9087
base.Validate();
9188
if (ChildContent is null)
9289
throw new ArgumentException($"No {nameof(ChildContent)} specified in the {GetType().Name} component.");
93-
if (Test is null && TestAsync is null && Tests?.Count == 0 && TestsAsync?.Count == 0)
90+
if (Test is null && TestAsync is null)
9491
throw new ArgumentException($"No test/assertions provided to the {GetType().Name} component.");
92+
if (Test is { } && TestAsync is { })
93+
throw new ArgumentException($"Only a single test method can be provided to the {GetType().Name} component at the time.");
94+
#pragma warning disable CS0618 // Type or member is obsolete
95+
if (Tests is { })
96+
throw new ArgumentException($"The user of the Tests parameter has been obsoleted, and any methods assigned to it will not longer be invoked.");
97+
if (TestsAsync is { })
98+
throw new ArgumentException($"The user of the TestsAsync parameter has been obsoleted, and any methods assigned to it will not longer be invoked.");
99+
#pragma warning restore CS0618 // Type or member is obsolete
95100
}
96101

97102
/// <inheritdoc/>
@@ -109,12 +114,6 @@ protected virtual async Task Run(TFixture self)
109114

110115
if (TestAsync is { })
111116
await TryRunAsync(TestAsync, self).ConfigureAwait(false);
112-
113-
foreach (var test in Tests ?? Array.Empty<Action<TFixture>>())
114-
TryRun(test, self);
115-
116-
foreach (var test in TestsAsync ?? Array.Empty<Func<TFixture, Task>>())
117-
await TryRunAsync(test, self).ConfigureAwait(false);
118117
}
119118
}
120119
}

src/bunit.core/RazorTesting/RazorTestBase.cs

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ namespace Bunit.RazorTesting
1010
/// </summary>
1111
public abstract class RazorTestBase : TestContextBase, ITestContext, IComponent
1212
{
13+
/// <summary>
14+
/// Gets the name of the test, which is displayed by the test runner/explorer.
15+
/// </summary>
16+
public abstract string? DisplayName { get; }
17+
1318
/// <summary>
1419
/// Gets whether the tests is running or not.
1520
/// </summary>
@@ -18,17 +23,17 @@ public abstract class RazorTestBase : TestContextBase, ITestContext, IComponent
1823
/// <summary>
1924
/// A description or name for the test that will be displayed if the test fails.
2025
/// </summary>
21-
[Parameter] public string? Description { get; set; }
26+
[Parameter] public virtual string? Description { get; set; }
2227

2328
/// <summary>
2429
/// Gets or sets a reason for skipping the test. If not set (null), the test will not be skipped.
2530
/// </summary>
26-
[Parameter] public string? Skip { get; set; }
31+
[Parameter] public virtual string? Skip { get; set; }
2732

2833
/// <summary>
2934
/// Gets or sets the timeout of the test, in milliseconds; if zero or negative, means the test case has no timeout.
3035
/// </summary>
31-
[Parameter] public int Timeout { get; set; } = 0;
36+
[Parameter] public virtual int Timeout { get; set; } = 0;
3237

3338
/// <summary>
3439
/// Run the test logic of the <see cref="RazorTestBase"/>.
@@ -78,35 +83,21 @@ void IComponent.Attach(RenderHandle renderHandle) { }
7883
/// <summary>
7984
/// Try to run the <see cref="Action{T}"/>.
8085
/// </summary>
81-
protected void TryRun<T>(Action<T> action, T input)
86+
protected static void TryRun<T>(Action<T> action, T input)
8287
{
8388
if (action is null)
8489
throw new ArgumentNullException(nameof(action));
85-
try
86-
{
87-
action(input);
88-
}
89-
catch (Exception ex)
90-
{
91-
throw new RazorTestFailedException(Description ?? $"{action.Method.Name} failed:", ex);
92-
}
90+
action(input);
9391
}
9492

9593
/// <summary>
9694
/// Try to run the <see cref="Func{T, Task}"/>.
9795
/// </summary>
98-
protected async Task TryRunAsync<T>(Func<T, Task> action, T input)
96+
protected static async Task TryRunAsync<T>(Func<T, Task> action, T input)
9997
{
10098
if (action is null)
10199
throw new ArgumentNullException(nameof(action));
102-
try
103-
{
104-
await action(input).ConfigureAwait(false);
105-
}
106-
catch (Exception ex)
107-
{
108-
throw new RazorTestFailedException(Description ?? $"{action.Method.Name} failed:", ex);
109-
}
100+
await action(input).ConfigureAwait(false);
110101
}
111102
}
112103
}

src/bunit.core/RazorTesting/RazorTestFailedException.cs

Lines changed: 0 additions & 20 deletions
This file was deleted.

src/bunit.core/Rendering/TestRenderer.cs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -180,35 +180,39 @@ private void AssertNoUnhandledExceptions()
180180
{
181181
if (frame.Component is TComponent component)
182182
return (frame.ComponentId, component);
183+
183184
var result = GetComponent<TComponent>(frame.ComponentId);
184-
if (result != null)
185+
if (result is { })
185186
return result;
186187
}
187188
}
188189

189-
throw new ComponentNotFoundException(typeof(TComponent));
190+
return null;
190191
}
191192

192193
private IReadOnlyList<(int ComponentId, TComponent Component)> GetComponents<TComponent>(int rootComponentId)
193194
{
194-
var ownFrames = GetCurrentRenderTreeFrames(rootComponentId);
195+
var result = new List<(int ComponentId, TComponent Component)>();
195196

196-
if (ownFrames.Count == 0)
197-
return Array.Empty<(int Id, TComponent Component)>();
197+
GetComponentsInternal(rootComponentId, result);
198198

199-
var result = new List<(int ComponentId, TComponent Component)>();
199+
return result;
200200

201-
for (var i = 0; i < ownFrames.Count; i++)
201+
void GetComponentsInternal(int rootComponentId, List<(int ComponentId, TComponent Component)> result)
202202
{
203-
ref var frame = ref ownFrames.Array[i];
204-
if (frame.FrameType == RenderTreeFrameType.Component)
203+
var ownFrames = GetCurrentRenderTreeFrames(rootComponentId);
204+
for (var i = 0; i < ownFrames.Count; i++)
205205
{
206-
if (frame.Component is TComponent component)
207-
result.Add((frame.ComponentId, component));
208-
result.AddRange(GetComponents<TComponent>(frame.ComponentId));
206+
ref var frame = ref ownFrames.Array[i];
207+
if (frame.FrameType == RenderTreeFrameType.Component)
208+
{
209+
if (frame.Component is TComponent component)
210+
result.Add((frame.ComponentId, component));
211+
212+
GetComponentsInternal(frame.ComponentId, result);
213+
}
209214
}
210215
}
211-
return result;
212216
}
213217
}
214218
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// This file is used by Code Analysis to maintain SuppressMessage
2+
// attributes that are applied to this project.
3+
// Project-level suppressions either have no target or are given
4+
// a specific target and scoped to a namespace, type, member, etc.
5+
6+
using System.Diagnostics.CodeAnalysis;
7+
8+
[assembly: SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters")]
9+
[assembly: SuppressMessage("Design", "CA1062:Validate arguments of public methods")]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace Bunit.TestAssets.SampleComponents.Data
2+
{
3+
public class ThemeInfo
4+
{
5+
public string? Value { get; set; }
6+
}
7+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<h1 @attributes="Attributes">Hello world</h1>
2+
@code {
3+
[Parameter(CaptureUnmatchedValues = true)]
4+
public IReadOnlyDictionary<string, object>? Attributes { get; set; }
5+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<button @onclick="HandleOnClick"
2+
class=@Theme?.Value
3+
title=@Title?.Value
4+
@attributes="Attributes">
5+
@ChildContent
6+
</button>
7+
@code {
8+
[Parameter(CaptureUnmatchedValues = true)]
9+
public IReadOnlyDictionary<string, object>? Attributes { get; set; }
10+
11+
[CascadingParameter] public ThemeInfo? Theme { get; set; }
12+
[CascadingParameter(Name = nameof(Title))] public ThemeInfo? Title { get; set; }
13+
[Parameter] public RenderFragment? ChildContent { get; set; }
14+
[Parameter] public EventCallback<MouseEventArgs> OnClick { get; set; }
15+
16+
private Task HandleOnClick(MouseEventArgs args) => OnClick.InvokeAsync(args);
17+
}

src/bunit.web.tests/Components/TestComponentBaseTest/BlazorElementReferencesIncludedInRenderedMarkup.razor

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)