Skip to content

Commit f2791a0

Browse files
committed
Added unit tests.
1 parent 532c22c commit f2791a0

File tree

2 files changed

+101
-24
lines changed

2 files changed

+101
-24
lines changed

src/Components/Web/test/Virtualization/VirtualizeTest.cs

Lines changed: 100 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,53 +3,130 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Linq;
67
using System.Threading.Tasks;
78
using Microsoft.AspNetCore.Components.Rendering;
89
using Microsoft.AspNetCore.Components.Test.Helpers;
910
using Microsoft.AspNetCore.Components.Web;
11+
using Microsoft.Extensions.DependencyInjection;
12+
using Microsoft.JSInterop;
13+
using Moq;
1014
using Xunit;
1115

1216
namespace Microsoft.AspNetCore.Components.Virtualization
1317
{
1418
public class VirtualizeTest
1519
{
16-
// TODO: Functional tests.
1720
[Fact]
18-
public void Virtualize_ThrowsWhenGivenNonPositiveItemSize()
21+
public async void Virtualize_ThrowsWhenGivenNonPositiveItemSize()
1922
{
2023
var rootComponent = new VirtualizeTestHostcomponent
2124
{
22-
InnerContent = BuildVirtualize(
23-
i => builder => { },
24-
null,
25-
context => builder => { },
26-
0f,
27-
null,
28-
new List<int>())
25+
InnerContent = BuildVirtualize(0f, EmptyItemsProvider<int>, null)
2926
};
3027

31-
var testRenderer = new TestRenderer();
28+
var serviceProvider = new ServiceCollection()
29+
.AddTransient((sp) => Mock.Of<IJSRuntime>())
30+
.BuildServiceProvider();
31+
32+
var testRenderer = new TestRenderer(serviceProvider);
33+
var componentId = testRenderer.AssignRootComponentId(rootComponent);
34+
35+
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await testRenderer.RenderRootComponentAsync(componentId));
36+
Assert.Contains("requires a positive value for parameter", ex.Message);
37+
}
38+
39+
[Fact]
40+
public async void Virtualize_ThrowsWhenGivenMultipleItemSources()
41+
{
42+
var rootComponent = new VirtualizeTestHostcomponent
43+
{
44+
InnerContent = BuildVirtualize(10f, EmptyItemsProvider<int>, new List<int>())
45+
};
46+
47+
var serviceProvider = new ServiceCollection()
48+
.AddTransient((sp) => Mock.Of<IJSRuntime>())
49+
.BuildServiceProvider();
50+
51+
var testRenderer = new TestRenderer(serviceProvider);
52+
var componentId = testRenderer.AssignRootComponentId(rootComponent);
53+
54+
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await testRenderer.RenderRootComponentAsync(componentId));
55+
Assert.Contains("can only accept one item source from its parameters", ex.Message);
56+
}
57+
58+
[Fact]
59+
public async void Virtualize_ThrowsWhenGivenNoItemSources()
60+
{
61+
var rootComponent = new VirtualizeTestHostcomponent
62+
{
63+
InnerContent = BuildVirtualize<int>(10f, null, null)
64+
};
65+
66+
var serviceProvider = new ServiceCollection()
67+
.AddTransient((sp) => Mock.Of<IJSRuntime>())
68+
.BuildServiceProvider();
69+
70+
var testRenderer = new TestRenderer(serviceProvider);
71+
var componentId = testRenderer.AssignRootComponentId(rootComponent);
72+
73+
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await testRenderer.RenderRootComponentAsync(componentId));
74+
Assert.Contains("parameters to be specified and non-null", ex.Message);
75+
}
76+
77+
[Fact]
78+
public async void Virtualize_DispatchesExceptionsFromItemsProviderThroughRenderer()
79+
{
80+
Virtualize<int> renderedVirtualize = null;
81+
82+
var rootComponent = new VirtualizeTestHostcomponent
83+
{
84+
InnerContent = BuildVirtualize(10f, AlwaysThrowsItemsProvider<int>, null, virtualize => renderedVirtualize = virtualize)
85+
};
86+
87+
var serviceProvider = new ServiceCollection()
88+
.AddTransient((sp) => Mock.Of<IJSRuntime>())
89+
.BuildServiceProvider();
90+
91+
var testRenderer = new TestRenderer(serviceProvider);
3292
var componentId = testRenderer.AssignRootComponentId(rootComponent);
3393

34-
var ex = Assert.Throws<InvalidOperationException>(() => testRenderer.RenderRootComponent(componentId));
94+
// Render to populate the component reference.
95+
await testRenderer.RenderRootComponentAsync(componentId);
96+
97+
Assert.NotNull(renderedVirtualize);
98+
99+
// Simulate a JS spacer callback.
100+
((IVirtualizeJsCallbacks)renderedVirtualize).OnAfterSpacerVisible(10f, 100f);
101+
102+
// Validate that the exception is dispatched through the renderer.
103+
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await testRenderer.RenderRootComponentAsync(componentId));
104+
Assert.Equal("Thrown from items provider.", ex.Message);
35105
}
36106

37-
public RenderFragment BuildVirtualize<TItem>(
38-
RenderFragment<TItem> childContent,
39-
RenderFragment<TItem> item,
40-
RenderFragment<PlaceholderContext> placeholder,
107+
private ValueTask<ItemsProviderResult<TItem>> EmptyItemsProvider<TItem>(ItemsProviderRequest request)
108+
=> ValueTask.FromResult(new ItemsProviderResult<TItem>(Enumerable.Empty<TItem>(), 0));
109+
110+
private ValueTask<ItemsProviderResult<TItem>> AlwaysThrowsItemsProvider<TItem>(ItemsProviderRequest request)
111+
=> throw new InvalidOperationException("Thrown from items provider.");
112+
113+
private RenderFragment BuildVirtualize<TItem>(
41114
float itemSize,
42115
ItemsProviderDelegate<TItem> itemsProvider,
43-
ICollection<TItem> items)
116+
ICollection<TItem> items,
117+
Action<Virtualize<TItem>> captureRenderedVirtualize = null)
44118
=> builder =>
45119
{
46120
builder.OpenComponent<Virtualize<TItem>>(0);
47-
builder.AddAttribute(1, "ChildContent", childContent);
48-
builder.AddAttribute(2, "Item", item);
49-
builder.AddAttribute(3, "Placeholder", placeholder);
50-
builder.AddAttribute(4, "ItemSize", itemSize);
51-
builder.AddAttribute(5, "ItemsProvider", itemsProvider);
52-
builder.AddAttribute(6, "Items", items);
121+
builder.AddAttribute(1, "ItemSize", itemSize);
122+
builder.AddAttribute(2, "ItemsProvider", itemsProvider);
123+
builder.AddAttribute(3, "Items", items);
124+
125+
if (captureRenderedVirtualize != null)
126+
{
127+
builder.AddComponentReferenceCapture(4, component => captureRenderedVirtualize(component as Virtualize<TItem>));
128+
}
129+
53130
builder.CloseComponent();
54131
};
55132

@@ -61,7 +138,7 @@ protected override void BuildRenderTree(RenderTreeBuilder builder)
61138
{
62139
builder.OpenElement(0, "div");
63140
builder.AddAttribute(1, "style", "overflow: auto; height: 800px;");
64-
builder.AddAttribute(2, "ChildContent", InnerContent);
141+
builder.AddContent(2, InnerContent);
65142
builder.CloseElement();
66143
}
67144
}

src/Components/test/testassets/TestServer/PrerenderedStartup.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public void ConfigureServices(IServiceCollection services)
2323
services.AddMvc();
2424
services.AddServerSideBlazor();
2525
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
26-
//services.AddSingleton<LazyAssemblyLoader>();
26+
services.AddSingleton<LazyAssemblyLoader>();
2727
}
2828

2929
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

0 commit comments

Comments
 (0)