Skip to content

Commit 6a4411a

Browse files
committed
refactor: moved stub<t> back to bunit.web, removed bunit.web.mock
1 parent a2225b5 commit 6a4411a

17 files changed

Lines changed: 297 additions & 228 deletions

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ All notable changes to **bUnit** will be documented in this file. The project ad
66

77
## [Unreleased]
88

9+
This release reintroduces `Stub<TComponent>` and related back into the main library, so the "preview" library `bunit.web.mock` is already obsolete.
10+
911
### Added
1012

1113
- Add `ComponentFactories` extensions method that makes it easy to register an instance of a replacement component. By [@egil](https://github.com/egil).

bunit.sln

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".workflows", ".workflows",
5959
.github\workflows\verification.yml = .github\workflows\verification.yml
6060
EndProjectSection
6161
EndProject
62-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bunit.web.mock", "src\bunit.web.mock\bunit.web.mock.csproj", "{3B51665F-E515-498A-8A82-BDB623089F9D}"
63-
EndProject
64-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bunit.web.mock.tests", "tests\bunit.web.mock.tests\bunit.web.mock.tests.csproj", "{050E57C2-C28F-4A9A-B35F-5725068AEF80}"
65-
EndProject
6662
Global
6763
GlobalSection(SolutionConfigurationPlatforms) = preSolution
6864
Debug|Any CPU = Debug|Any CPU
@@ -101,14 +97,6 @@ Global
10197
{4CAB561E-0AFF-4516-AB9B-981F94EF1E86}.Debug|Any CPU.Build.0 = Debug|Any CPU
10298
{4CAB561E-0AFF-4516-AB9B-981F94EF1E86}.Release|Any CPU.ActiveCfg = Release|Any CPU
10399
{4CAB561E-0AFF-4516-AB9B-981F94EF1E86}.Release|Any CPU.Build.0 = Release|Any CPU
104-
{3B51665F-E515-498A-8A82-BDB623089F9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
105-
{3B51665F-E515-498A-8A82-BDB623089F9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
106-
{3B51665F-E515-498A-8A82-BDB623089F9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
107-
{3B51665F-E515-498A-8A82-BDB623089F9D}.Release|Any CPU.Build.0 = Release|Any CPU
108-
{050E57C2-C28F-4A9A-B35F-5725068AEF80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
109-
{050E57C2-C28F-4A9A-B35F-5725068AEF80}.Debug|Any CPU.Build.0 = Debug|Any CPU
110-
{050E57C2-C28F-4A9A-B35F-5725068AEF80}.Release|Any CPU.ActiveCfg = Release|Any CPU
111-
{050E57C2-C28F-4A9A-B35F-5725068AEF80}.Release|Any CPU.Build.0 = Release|Any CPU
112100
EndGlobalSection
113101
GlobalSection(SolutionProperties) = preSolution
114102
HideSolutionNode = FALSE
@@ -123,8 +111,6 @@ Global
123111
{7972A80F-30DC-4EF4-9294-7D4DD2965882} = {6EA09ED4-B714-4E6F-B0E1-4D987F8AE520}
124112
{F61B8A55-3B5B-45FB-8E38-DBF9296B35C7} = {9A2B3B34-D41C-43E8-BC7D-246BEBE48D59}
125113
{4CAB561E-0AFF-4516-AB9B-981F94EF1E86} = {6EA09ED4-B714-4E6F-B0E1-4D987F8AE520}
126-
{3B51665F-E515-498A-8A82-BDB623089F9D} = {9A2B3B34-D41C-43E8-BC7D-246BEBE48D59}
127-
{050E57C2-C28F-4A9A-B35F-5725068AEF80} = {6EA09ED4-B714-4E6F-B0E1-4D987F8AE520}
128114
EndGlobalSection
129115
GlobalSection(ExtensibilityGlobals) = postSolution
130116
SolutionGuid = {24106918-1C86-4769-BDA6-9C80E64CD260}

src/bunit.web.mock/TestDoubles/Components/Stub{TComponent}.cs

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

src/bunit.web.mock/bunit.web.mock.csproj

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

src/bunit.web.mock/ComponentFactories/StubComponentFactory.cs renamed to src/bunit.web/ComponentFactories/StubComponentFactory.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ internal sealed class StubComponentFactory : IComponentFactory
88
private static readonly Type StubType = typeof(Stub<>);
99

1010
private readonly Predicate<Type> componentTypePredicate;
11-
private readonly RenderFragment<IReadOnlyDictionary<string, object>>? replacementTemplate;
11+
private readonly object? replacementContent;
1212

13-
public StubComponentFactory(Predicate<Type> componentTypePredicate, RenderFragment<IReadOnlyDictionary<string, object>>? replacementTemplate = null)
13+
public StubComponentFactory(Predicate<Type> componentTypePredicate, object? replacementContent)
1414
{
1515
this.componentTypePredicate = componentTypePredicate;
16-
this.replacementTemplate = replacementTemplate;
16+
this.replacementContent = replacementContent;
1717
}
1818

1919
public bool CanCreate(Type componentType)
@@ -22,7 +22,9 @@ public bool CanCreate(Type componentType)
2222
public IComponent Create(Type componentType)
2323
{
2424
var typeToCreate = StubType.MakeGenericType(componentType);
25-
return (IComponent)Activator.CreateInstance(typeToCreate, new object?[] { replacementTemplate })!;
25+
return replacementContent is not null
26+
? (IComponent)Activator.CreateInstance(typeToCreate, new object?[] { replacementContent })!
27+
: (IComponent)Activator.CreateInstance(typeToCreate, Array.Empty<object?>())!;
2628
}
2729
}
2830
#endif

src/bunit.web.mock/Extensions/ComponentFactoryCollectionExtensions.cs renamed to src/bunit.web/Extensions/StubComponentFactoryCollectionExtensions.cs

Lines changed: 68 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#if NET5_0_OR_GREATER
12
using Bunit.ComponentFactories;
23
using Bunit.TestDoubles;
34

@@ -6,10 +7,8 @@ namespace Bunit;
67
/// <summary>
78
/// Extension methods for using component doubles.
89
/// </summary>
9-
public static class ComponentFactoryCollectionExtensions
10+
public static class StubComponentFactoryCollectionExtensions
1011
{
11-
private static readonly RenderFragment<IReadOnlyDictionary<string, object>> NoopReplacementTemplate = _ => _ => { };
12-
1312
/// <summary>
1413
/// Configures bUnit to use replace all components of type <typeparamref name="TComponent"/> (including derived components)
1514
/// with a <see cref="Stub{TComponent}"/> component in the render tree.
@@ -19,7 +18,17 @@ public static class ComponentFactoryCollectionExtensions
1918
/// <param name="factories">The bUnit <see cref="ComponentFactoryCollection"/> to configure.</param>
2019
/// <returns>A <see cref="ComponentFactoryCollection"/>.</returns>
2120
public static ComponentFactoryCollection AddStub<TComponent>(this ComponentFactoryCollection factories) where TComponent : IComponent
22-
=> AddStub<TComponent>(factories, NoopReplacementTemplate);
21+
{
22+
if (factories is null)
23+
throw new ArgumentNullException(nameof(factories));
24+
25+
factories.Add(new StubComponentFactory(CreatePredicate(typeof(TComponent)), null));
26+
27+
return factories;
28+
29+
static Predicate<Type> CreatePredicate(Type componentTypeToStub)
30+
=> componentType => componentType == componentTypeToStub || componentType.IsAssignableTo(componentTypeToStub);
31+
}
2332

2433
/// <summary>
2534
/// Configures bUnit to use replace all components of type <typeparamref name="TComponent"/> (including derived components)
@@ -28,16 +37,48 @@ public static ComponentFactoryCollection AddStub<TComponent>(this ComponentFacto
2837
/// <remarks>NOTE: This will replace any component of type <typeparamref name="TComponent"/> or components that derives/inherits from it.</remarks>
2938
/// <typeparam name="TComponent">The type of component to replace with a <see cref="Stub{TComponent}"/> component.</typeparam>
3039
/// <param name="factories">The bUnit <see cref="ComponentFactoryCollection"/> to configure.</param>
31-
/// <param name="replacementTemplate">Optional replacement template that will be used to render output instead of the stubbed out component.</param>
40+
/// <param name="replacementMarkup">Markup that will be used as render output instead of the stubbed out component.</param>
41+
/// <returns>A <see cref="ComponentFactoryCollection"/>.</returns>
42+
public static ComponentFactoryCollection AddStub<TComponent>(this ComponentFactoryCollection factories, string replacementMarkup) where TComponent : IComponent
43+
=> AddStub<TComponent>(factories, (RenderTreeBuilder b) => b.AddMarkupContent(0, replacementMarkup));
44+
45+
/// <summary>
46+
/// Configures bUnit to use replace all components of type <typeparamref name="TComponent"/> (including derived components)
47+
/// with a <see cref="Stub{TComponent}"/> component in the render tree.
48+
/// </summary>
49+
/// <remarks>NOTE: This will replace any component of type <typeparamref name="TComponent"/> or components that derives/inherits from it.</remarks>
50+
/// <typeparam name="TComponent">The type of component to replace with a <see cref="Stub{TComponent}"/> component.</typeparam>
51+
/// <param name="factories">The bUnit <see cref="ComponentFactoryCollection"/> to configure.</param>
52+
/// <param name="replacementFragment">Replacement render fragment that will be used as render output instead of the stubbed out component.</param>
53+
/// <returns>A <see cref="ComponentFactoryCollection"/>.</returns>
54+
public static ComponentFactoryCollection AddStub<TComponent>(this ComponentFactoryCollection factories, RenderFragment replacementFragment) where TComponent : IComponent
55+
{
56+
if (factories is null)
57+
throw new ArgumentNullException(nameof(factories));
58+
59+
factories.Add(new StubComponentFactory(CreatePredicate(typeof(TComponent)), replacementFragment));
60+
61+
return factories;
62+
63+
static Predicate<Type> CreatePredicate(Type componentTypeToStub)
64+
=> componentType => componentType == componentTypeToStub || componentType.IsAssignableTo(componentTypeToStub);
65+
}
66+
67+
/// <summary>
68+
/// Configures bUnit to use replace all components of type <typeparamref name="TComponent"/> (including derived components)
69+
/// with a <see cref="Stub{TComponent}"/> component in the render tree.
70+
/// </summary>
71+
/// <remarks>NOTE: This will replace any component of type <typeparamref name="TComponent"/> or components that derives/inherits from it.</remarks>
72+
/// <typeparam name="TComponent">The type of component to replace with a <see cref="Stub{TComponent}"/> component.</typeparam>
73+
/// <param name="factories">The bUnit <see cref="ComponentFactoryCollection"/> to configure.</param>
74+
/// <param name="replacementTemplate">Replacement template that will be used to render output instead of the stubbed out component.</param>
3275
/// <returns>A <see cref="ComponentFactoryCollection"/>.</returns>
3376
public static ComponentFactoryCollection AddStub<TComponent>(
3477
this ComponentFactoryCollection factories,
35-
Func<IReadOnlyDictionary<string, object>, string> replacementTemplate)
78+
Func<CapturedParameterView<TComponent>, string> replacementTemplate)
3679
where TComponent : IComponent
3780
{
38-
return AddStub<TComponent>(
39-
factories,
40-
ps => b => b.AddMarkupContent(0, replacementTemplate(ps)));
81+
return AddStub<TComponent>(factories, ps => b => b.AddMarkupContent(0, replacementTemplate(ps)));
4182
}
4283

4384
/// <summary>
@@ -47,14 +88,21 @@ public static ComponentFactoryCollection AddStub<TComponent>(
4788
/// <remarks>NOTE: This will replace any component of type <typeparamref name="TComponent"/> or components that derives/inherits from it.</remarks>
4889
/// <typeparam name="TComponent">The type of component to replace with a <see cref="Stub{TComponent}"/> component.</typeparam>
4990
/// <param name="factories">The bUnit <see cref="ComponentFactoryCollection"/> to configure.</param>
50-
/// <param name="replacementTemplate">Optional replacement template that will be used to render output instead of the stubbed out component.</param>
91+
/// <param name="replacementTemplate">Replacement template that will be used to render output instead of the stubbed out component.</param>
5192
/// <returns>A <see cref="ComponentFactoryCollection"/>.</returns>
5293
public static ComponentFactoryCollection AddStub<TComponent>(
5394
this ComponentFactoryCollection factories,
54-
RenderFragment<IReadOnlyDictionary<string, object>> replacementTemplate)
95+
RenderFragment<CapturedParameterView<TComponent>> replacementTemplate)
5596
where TComponent : IComponent
5697
{
57-
return AddStub(factories, CreatePredicate(typeof(TComponent)), replacementTemplate);
98+
if (factories is null)
99+
throw new ArgumentNullException(nameof(factories));
100+
if (replacementTemplate is null)
101+
throw new ArgumentNullException(nameof(replacementTemplate));
102+
103+
factories.Add(new StubComponentFactory(CreatePredicate(typeof(TComponent)), replacementTemplate));
104+
105+
return factories;
58106

59107
static Predicate<Type> CreatePredicate(Type componentTypeToStub)
60108
=> componentType => componentType == componentTypeToStub || componentType.IsAssignableTo(componentTypeToStub);
@@ -73,44 +121,45 @@ public static ComponentFactoryCollection AddStub(
73121
=> AddStub(
74122
factories,
75123
componentTypePredicate,
76-
NoopReplacementTemplate);
124+
string.Empty);
77125

78126
/// <summary>
79127
/// Configures bUnit to use replace all components whose type make the <paramref name="componentTypePredicate"/> predicate return <c>true</c>
80128
/// with a <see cref="Stub{TComponent}"/> component in the render tree.
81129
/// </summary>
82130
/// <param name="factories">The bUnit <see cref="ComponentFactoryCollection"/> to configure.</param>
83131
/// <param name="componentTypePredicate">The predicate which decides if a component should be replaced with a <see cref="Stub{TComponent}"/> component.</param>
84-
/// <param name="replacementTemplate">Optional replacement template that will be used to render output instead of the stubbed out component.</param>
132+
/// <param name="replacementMarkup">Replacement markup that will be used to render output instead of the stubbed out components.</param>
85133
/// <returns>A <see cref="ComponentFactoryCollection"/>.</returns>
86134
public static ComponentFactoryCollection AddStub(
87135
this ComponentFactoryCollection factories,
88136
Predicate<Type> componentTypePredicate,
89-
Func<IReadOnlyDictionary<string, object>, string> replacementTemplate)
137+
string replacementMarkup)
90138
=> AddStub(
91139
factories,
92140
componentTypePredicate,
93-
ps => b => b.AddMarkupContent(0, replacementTemplate(ps)));
141+
b => b.AddMarkupContent(0, replacementMarkup));
94142

95143
/// <summary>
96144
/// Configures bUnit to use replace all components whose type make the <paramref name="componentTypePredicate"/> predicate return <c>true</c>
97145
/// with a <see cref="Stub{TComponent}"/> component in the render tree.
98146
/// </summary>
99147
/// <param name="factories">The bUnit <see cref="ComponentFactoryCollection"/> to configure.</param>
100148
/// <param name="componentTypePredicate">The predicate which decides if a component should be replaced with a <see cref="Stub{TComponent}"/> component.</param>
101-
/// <param name="replacementTemplate">Optional replacement template that will be used to render output instead of the stubbed out component.</param>
149+
/// <param name="replacementFragment">Replacement <see cref="RenderFragment"/> that will be used to render output instead of the stubbed out components.</param>
102150
/// <returns>A <see cref="ComponentFactoryCollection"/>.</returns>
103151
public static ComponentFactoryCollection AddStub(
104152
this ComponentFactoryCollection factories,
105153
Predicate<Type> componentTypePredicate,
106-
RenderFragment<IReadOnlyDictionary<string, object>> replacementTemplate)
154+
RenderFragment replacementFragment)
107155
{
108156
if (factories is null)
109157
throw new ArgumentNullException(nameof(factories));
110158
if (componentTypePredicate is null)
111159
throw new ArgumentNullException(nameof(componentTypePredicate));
112160

113-
factories.Add(new StubComponentFactory(componentTypePredicate, replacementTemplate));
161+
factories.Add(new StubComponentFactory(componentTypePredicate, replacementFragment));
114162
return factories;
115163
}
116164
}
165+
#endif

0 commit comments

Comments
 (0)