fix(module: table): fix collection modified exception (#570)
This commit is contained in:
Родитель
b257d17844
Коммит
7119351b9f
|
@ -15,6 +15,7 @@
|
||||||
<Copyright>James Yeung</Copyright>
|
<Copyright>James Yeung</Copyright>
|
||||||
<Authors>James Yeung</Authors>
|
<Authors>James Yeung</Authors>
|
||||||
<PackageIcon>logo.png</PackageIcon>
|
<PackageIcon>logo.png</PackageIcon>
|
||||||
|
<NoWarn>CA2007</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
|
|
@ -27,10 +27,7 @@ namespace AntDesign
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < items.Count(); i++)
|
foreach (var item in items) await func(item);
|
||||||
{
|
|
||||||
await func(items.ElementAt(i));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsIn<T>(this T source, params T[] array)
|
public static bool IsIn<T>(this T source, params T[] array)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using AntDesign.TableModels;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using AntDesign.TableModels;
|
||||||
|
|
||||||
namespace AntDesign
|
namespace AntDesign
|
||||||
{
|
{
|
||||||
|
@ -32,8 +32,8 @@ namespace AntDesign
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Clear cached items that are not on current page
|
// Clear cached items that are not on current page
|
||||||
var currentPageCacheKeys = _selection.RowSelections.Select(x => x.CacheKey);
|
var currentPageCacheKeys = _selection.RowSelections.Select(x => x.CacheKey).ToHashSet();
|
||||||
var deletedCaches = _dataSourceCache.Where(x => x.Value.PageIndex == PageIndex && !x.Key.IsIn(currentPageCacheKeys));
|
var deletedCaches = _dataSourceCache.Where(x => x.Value.PageIndex == PageIndex && !currentPageCacheKeys.Contains(x.Key)).ToList();
|
||||||
var needInvokeChange = deletedCaches.Any(x => x.Value.Selected);
|
var needInvokeChange = deletedCaches.Any(x => x.Value.Selected);
|
||||||
deletedCaches.ForEach(x => _dataSourceCache.Remove(x));
|
deletedCaches.ForEach(x => _dataSourceCache.Remove(x));
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,8 @@ namespace AntDesign
|
||||||
_showItems = _dataSource;
|
_showItems = _dataSource;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (_dataSource != null)
|
||||||
{
|
{
|
||||||
var query = _dataSource.AsQueryable();
|
var query = _dataSource.AsQueryable();
|
||||||
foreach (var sort in queryModel.SortModel)
|
foreach (var sort in queryModel.SortModel)
|
||||||
|
@ -121,6 +123,7 @@ namespace AntDesign
|
||||||
|
|
||||||
_showItems = query;
|
_showItems = query;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
<link href="../../components/wwwroot/css/ant-design-blazor.css" rel="stylesheet">
|
||||||
|
<div class="ant-table-wrapper">
|
||||||
|
<div class="ant-spin-nested-loading">
|
||||||
|
<div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="ant-spin-container ">
|
||||||
|
|
||||||
|
|
||||||
|
<div class=" ant-table ant-table-middle">
|
||||||
|
<div class="ant-table-container">
|
||||||
|
<div class="ant-table-content">
|
||||||
|
<table style="table-layout: auto;">
|
||||||
|
|
||||||
|
|
||||||
|
<colgroup>
|
||||||
|
</colgroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<thead class="ant-table-thead">
|
||||||
|
<tr>
|
||||||
|
|
||||||
|
|
||||||
|
<th class=" ant-table-cell" style=" " blazor:onclick="4">
|
||||||
|
</th>
|
||||||
|
<th class=" ant-table-cell" style=" " blazor:onclick="5">
|
||||||
|
</th>
|
||||||
|
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody class="ant-table-tbody">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<tr data-row-id="2" class="ant-table-row ant-table-row-level-0 ">
|
||||||
|
<td class=" ant-table-cell" style=" ">
|
||||||
|
Joe </td>
|
||||||
|
<td class=" ant-table-cell" style=" ">
|
||||||
|
Doe </td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<ul class="ant-table-pagination ant-table-pagination-right ant-pagination" id:ignore blazor:elementreference="">
|
||||||
|
|
||||||
|
<li class=" ant-pagination-prev" title="上一页" id:ignore blazor:onclick="1" blazor:elementreference="">
|
||||||
|
|
||||||
|
|
||||||
|
<a class="ant-pagination-item-link">
|
||||||
|
<span role="img" class=" anticon anticon-left" id:ignore blazor:onclick="6">
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class=" ant-pagination-item" title="1" id:ignore blazor:onclick="2" blazor:elementreference="">
|
||||||
|
|
||||||
|
|
||||||
|
<a>1</a>
|
||||||
|
</li>
|
||||||
|
<li class=" ant-pagination-item ant-pagination-item-active" title="2" id:ignore blazor:onclick="8" blazor:elementreference="">
|
||||||
|
|
||||||
|
|
||||||
|
<a>2</a>
|
||||||
|
</li>
|
||||||
|
<li class=" ant-pagination-next ant-pagination-disabled" title="下一页" id:ignore blazor:onclick="12" blazor:elementreference="">
|
||||||
|
|
||||||
|
|
||||||
|
<a class="ant-pagination-item-link">
|
||||||
|
<span role="img" class=" anticon anticon-right" id:ignore blazor:onclick="13">
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
|
@ -0,0 +1,104 @@
|
||||||
|
<link href="../../components/wwwroot/css/ant-design-blazor.css" rel="stylesheet">
|
||||||
|
<div class="ant-table-wrapper">
|
||||||
|
<div class="ant-spin-nested-loading">
|
||||||
|
<div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="ant-spin-container ">
|
||||||
|
|
||||||
|
|
||||||
|
<div class=" ant-table ant-table-middle">
|
||||||
|
<div class="ant-table-container">
|
||||||
|
<div class="ant-table-content">
|
||||||
|
<table style="table-layout: auto;">
|
||||||
|
|
||||||
|
|
||||||
|
<colgroup>
|
||||||
|
</colgroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<thead class="ant-table-thead">
|
||||||
|
<tr>
|
||||||
|
|
||||||
|
|
||||||
|
<th class=" ant-table-cell" style=" " blazor:onclick="4">
|
||||||
|
</th>
|
||||||
|
<th class=" ant-table-cell" style=" " blazor:onclick="5">
|
||||||
|
</th>
|
||||||
|
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody class="ant-table-tbody">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<tr data-row-id="1" class="ant-table-row ant-table-row-level-0 ">
|
||||||
|
<td class=" ant-table-cell" style=" ">
|
||||||
|
John </td>
|
||||||
|
<td class=" ant-table-cell" style=" ">
|
||||||
|
Smith </td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<tr data-row-id="2" class="ant-table-row ant-table-row-level-0 ">
|
||||||
|
<td class=" ant-table-cell" style=" ">
|
||||||
|
Jane </td>
|
||||||
|
<td class=" ant-table-cell" style=" ">
|
||||||
|
Doe </td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<ul class="ant-table-pagination ant-table-pagination-right ant-pagination" id:ignore blazor:elementreference="">
|
||||||
|
|
||||||
|
<li class=" ant-pagination-prev ant-pagination-disabled" title="上一页" id:ignore blazor:onclick="1" blazor:elementreference="">
|
||||||
|
|
||||||
|
|
||||||
|
<a class="ant-pagination-item-link">
|
||||||
|
<span role="img" class=" anticon anticon-left" id:ignore blazor:onclick="6">
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class=" ant-pagination-item ant-pagination-item-active" title="1" id:ignore blazor:onclick="2" blazor:elementreference="">
|
||||||
|
|
||||||
|
|
||||||
|
<a>1</a>
|
||||||
|
</li>
|
||||||
|
<li class=" ant-pagination-next ant-pagination-disabled" title="下一页" id:ignore blazor:onclick="3" blazor:elementreference="">
|
||||||
|
|
||||||
|
|
||||||
|
<a class="ant-pagination-item-link">
|
||||||
|
<span role="img" class=" anticon anticon-right" id:ignore blazor:onclick="7">
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
|
@ -0,0 +1,99 @@
|
||||||
|
<link href="../../components/wwwroot/css/ant-design-blazor.css" rel="stylesheet">
|
||||||
|
<div class="ant-table-wrapper">
|
||||||
|
<div class="ant-spin-nested-loading">
|
||||||
|
<div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="ant-spin-container ">
|
||||||
|
|
||||||
|
|
||||||
|
<div class=" ant-table ant-table-middle">
|
||||||
|
<div class="ant-table-container">
|
||||||
|
<div class="ant-table-content">
|
||||||
|
<table style="table-layout: auto;">
|
||||||
|
|
||||||
|
|
||||||
|
<colgroup>
|
||||||
|
</colgroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<thead class="ant-table-thead">
|
||||||
|
<tr>
|
||||||
|
|
||||||
|
|
||||||
|
<th class=" ant-table-cell" style=" " blazor:onclick="4">
|
||||||
|
</th>
|
||||||
|
<th class=" ant-table-cell" style=" " blazor:onclick="5">
|
||||||
|
</th>
|
||||||
|
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody class="ant-table-tbody">
|
||||||
|
|
||||||
|
|
||||||
|
<tr class="ant-table-placeholder">
|
||||||
|
<td colspan="2" class="ant-table-cell">
|
||||||
|
<div class="ant-empty ant-empty-ltr" id:ignore blazor:elementreference:ignore>
|
||||||
|
<div class="ant-empty-image">
|
||||||
|
<svg class="ant-empty-img-simple" width="64" height="41" viewBox="0 0 64 41" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g transform="translate(0 1)" fill="none" fillRule="evenodd">
|
||||||
|
<ellipse class="ant-empty-img-simple-ellipse" cx="32" cy="33" rx="32" ry="7"></ellipse>
|
||||||
|
<g class="ant-empty-img-simple-g" fillRule="nonzero">
|
||||||
|
<path d="M55 12.76L44.854 1.258C44.367.474 43.656 0 42.907 0H21.093c-.749 0-1.46.474-1.947 1.257L9 12.761V22h46v-9.24z"></path>
|
||||||
|
<path d="M41.613 15.931c0-1.605.994-2.93 2.227-2.931H55v18.137C55 33.26 53.68 35 52.05 35h-40.1C10.32 35 9 33.259 9 31.137V13h11.16c1.233 0 2.227 1.323 2.227 2.928v.022c0 1.605 1.005 2.901 2.237 2.901h14.752c1.232 0 2.237-1.308 2.237-2.913v-.007z" class="ant-empty-img-simple-path"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg> </div>
|
||||||
|
|
||||||
|
<p class="ant-empty-description">暂无数据</p>
|
||||||
|
<div class="ant-empty-footer">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<ul class="ant-table-pagination ant-table-pagination-right ant-pagination" id:ignore blazor:elementreference="">
|
||||||
|
|
||||||
|
<li class=" ant-pagination-prev ant-pagination-disabled" title="上一页" id:ignore blazor:onclick="1" blazor:elementreference="">
|
||||||
|
|
||||||
|
|
||||||
|
<a class="ant-pagination-item-link">
|
||||||
|
<span role="img" class=" anticon anticon-left" id:ignore blazor:onclick="6">
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class=" ant-pagination-item ant-pagination-item-active" title="1" id:ignore blazor:onclick="2" blazor:elementreference="">
|
||||||
|
|
||||||
|
|
||||||
|
<a>1</a>
|
||||||
|
</li>
|
||||||
|
<li class=" ant-pagination-next ant-pagination-disabled" title="下一页" id:ignore blazor:onclick="3" blazor:elementreference="">
|
||||||
|
|
||||||
|
|
||||||
|
<a class="ant-pagination-item-link">
|
||||||
|
<span role="img" class=" anticon anticon-right" id:ignore blazor:onclick="7">
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
|
@ -20,4 +20,8 @@
|
||||||
<ProjectReference Include="..\components\AntDesign.csproj" />
|
<ProjectReference Include="..\components\AntDesign.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="$Recorded" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using Bunit;
|
using Bunit;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace AntDesign.Tests
|
namespace AntDesign.Tests
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Bunit;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Xunit;
|
||||||
|
using Xunit.Sdk;
|
||||||
|
|
||||||
|
namespace AntDesign.Tests
|
||||||
|
{
|
||||||
|
public static class RecordedTestExtensions
|
||||||
|
{
|
||||||
|
private const string Style =
|
||||||
|
"<link href=\"../../components/wwwroot/css/ant-design-blazor.css\" rel=\"stylesheet\">\n";
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
public static void RecordedMarkupMatches<T>(this IRenderedComponent<T> component) where T : notnull, IComponent
|
||||||
|
{
|
||||||
|
static string Cleanup(string value)
|
||||||
|
{
|
||||||
|
value = Regex.Replace(value, "id=\"ant-blazor-.+?\"", "id:ignore");
|
||||||
|
value = Regex.Replace(value, "blazor:elementreference=\".+?\"", "blazor:elementreference:ignore");
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var caller = new StackTrace().GetFrame(1)?.GetMethod();
|
||||||
|
RecordedMarkupMatches(
|
||||||
|
component.Markup,
|
||||||
|
caller,
|
||||||
|
expected => component.MarkupMatches(expected),
|
||||||
|
Cleanup
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RecordedMarkupMatches(string markup)
|
||||||
|
{
|
||||||
|
var caller = new StackTrace().GetFrame(1)?.GetMethod();
|
||||||
|
RecordedMarkupMatches(
|
||||||
|
markup,
|
||||||
|
caller,
|
||||||
|
expected => Assert.Equal(markup, expected),
|
||||||
|
m => m
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RecordedMarkupMatches(string markup, MethodBase caller, Action<string> assert,
|
||||||
|
Func<string, string> transform)
|
||||||
|
{
|
||||||
|
if (caller == null)
|
||||||
|
throw new XunitException("Cannot find caller from StackTrace.");
|
||||||
|
|
||||||
|
if (caller.ReflectedType == null)
|
||||||
|
throw new XunitException("Cannot access ReflectedType for the method.");
|
||||||
|
|
||||||
|
// Here we make an assumption that project is not following an unconventional directory structure.
|
||||||
|
var expectedPath = $"{Path.DirectorySeparatorChar}bin{Path.DirectorySeparatorChar}";
|
||||||
|
var parts = caller.ReflectedType.Assembly.Location.Split(expectedPath);
|
||||||
|
if (parts.Length == 1)
|
||||||
|
throw new XunitException($"Path does not include ${expectedPath}");
|
||||||
|
|
||||||
|
var recordedTestsPath = Path.Combine(parts[0], "$Recorded");
|
||||||
|
|
||||||
|
if (!Directory.Exists(recordedTestsPath))
|
||||||
|
Directory.CreateDirectory(recordedTestsPath);
|
||||||
|
|
||||||
|
var sanitisedFileName = Path.GetInvalidFileNameChars()
|
||||||
|
.Aggregate(new StringBuilder($"{caller.ReflectedType}{caller.Name}.html"),
|
||||||
|
(builder, c) => builder.Replace(c, '_'))
|
||||||
|
.ToString();
|
||||||
|
|
||||||
|
var testFile = Path.Combine(recordedTestsPath, sanitisedFileName);
|
||||||
|
|
||||||
|
if (File.Exists(testFile))
|
||||||
|
{
|
||||||
|
var expected = File.ReadAllText(testFile);
|
||||||
|
assert(expected.Replace(Style, ""));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
File.WriteAllText(testFile, Style + transform(markup));
|
||||||
|
throw new XunitException(
|
||||||
|
"Test file for comparison was not found, so a new one was created. Please review the file before re-running the test.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Bunit;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace AntDesign.Tests.Table
|
||||||
|
{
|
||||||
|
public class TableTests : AntDesignTestBase
|
||||||
|
{
|
||||||
|
class Person
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Surname { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private IRenderedComponent<Table<Person>> CreatePersonsTable(
|
||||||
|
IReadOnlyList<Person> persons,
|
||||||
|
Action<ComponentParameterBuilder<Table<Person>>> callback = null,
|
||||||
|
bool enableSelection = false)
|
||||||
|
{
|
||||||
|
return Context.RenderComponent<Table<Person>>(x =>
|
||||||
|
{
|
||||||
|
x
|
||||||
|
.Add(b => b.DataSource, persons)
|
||||||
|
.Add(b => b.ChildContent, p =>
|
||||||
|
{
|
||||||
|
var selection = new ComponentParameterBuilder<Selection>()
|
||||||
|
.Add(q => q.Key, p.Id.ToString())
|
||||||
|
.Build()
|
||||||
|
.ToComponentRenderFragment<Selection>();
|
||||||
|
|
||||||
|
var nameCol = new ComponentParameterBuilder<Column<string>>()
|
||||||
|
.Add(q => q.Field, p.Name)
|
||||||
|
.Build()
|
||||||
|
.ToComponentRenderFragment<Column<string>>();
|
||||||
|
|
||||||
|
var surnameCol = new ComponentParameterBuilder<Column<string>>()
|
||||||
|
.Add(q => q.Field, p.Surname)
|
||||||
|
.Build()
|
||||||
|
.ToComponentRenderFragment<Column<string>>();
|
||||||
|
|
||||||
|
return builder =>
|
||||||
|
{
|
||||||
|
if (enableSelection) selection(builder);
|
||||||
|
nameCol(builder);
|
||||||
|
surnameCol(builder);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
callback?.Invoke(x);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Renders_an_empty_table()
|
||||||
|
{
|
||||||
|
var persons = Array.Empty<Person>();
|
||||||
|
|
||||||
|
var cut = CreatePersonsTable(persons);
|
||||||
|
|
||||||
|
cut.RecordedMarkupMatches();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Renders_a_table_with_two_rows()
|
||||||
|
{
|
||||||
|
var persons = new[]
|
||||||
|
{
|
||||||
|
new Person {Id = 1, Name = "John", Surname = "Smith"},
|
||||||
|
new Person {Id = 2, Name = "Jane", Surname = "Doe"}
|
||||||
|
};
|
||||||
|
|
||||||
|
var cut = CreatePersonsTable(persons);
|
||||||
|
|
||||||
|
cut.RecordedMarkupMatches();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Can_render_after_changes_to_the_dataSource()
|
||||||
|
{
|
||||||
|
var persons = new List<Person>
|
||||||
|
{
|
||||||
|
new Person {Id = 1, Name = "John", Surname = "Smith"},
|
||||||
|
new Person {Id = 2, Name = "Jane", Surname = "Doe"},
|
||||||
|
new Person {Id = 3, Name = "Joe", Surname = "Doe"}
|
||||||
|
};
|
||||||
|
|
||||||
|
var cut = CreatePersonsTable(persons, b => b
|
||||||
|
.Add(q => q.PageSize, 1)
|
||||||
|
.Add(q => q.PageIndex, 3)
|
||||||
|
);
|
||||||
|
|
||||||
|
persons.RemoveAt(0);
|
||||||
|
|
||||||
|
cut.SetParametersAndRender(b => b.Add(q => q.DataSource, persons));
|
||||||
|
|
||||||
|
cut.RecordedMarkupMatches();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче