public void Can_Set_Custom_Attributes() { var row = new MyDto { Name = "Unit test" }; Expression <Func <string> > colFor = () => row.Name; ProviderDelegate <MyDto> provider = (r, _) => { return(ValueTask.FromResult(new BlazorGridResult <MyDto> { TotalCount = 1, Data = new List <MyDto> { row } })); }; var grid = RenderComponent <BlazorGrid <MyDto> >( Parameter(nameof(BlazorGrid <MyDto> .Provider), provider), Template <MyDto>(nameof(ChildContent), (context) => (RenderTreeBuilder builder) => { builder.OpenComponent <GridCol <string> >(0); builder.AddAttribute(1, nameof(GridCol <string> .For), colFor); builder.AddAttribute(2, "title", "Hello world"); builder.CloseComponent(); }) ); var rowElement = grid.FindAll(".grid-row").Last(); rowElement.MarkupMatches("<div class=\"grid-row\"><div title=\"Hello world\">Unit test</div></div>"); }
public async Task Sorting_Triggers_Rerender() { ProviderDelegate <MyDto> provider = (r, _) => { return(ValueTask.FromResult(new BlazorGridResult <MyDto> { TotalCount = 1, Data = new List <MyDto> { new MyDto { Name = "Unit test" } } })); }; var grid = RenderComponent <BlazorGrid <MyDto> >( Parameter(nameof(BlazorGrid <MyDto> .Provider), provider), Template <MyDto>(nameof(ChildContent), (context) => (RenderTreeBuilder b) => { Expression <Func <string> > colFor = () => context.Name; b.OpenComponent <GridCol <string> >(0); b.AddAttribute(1, "For", colFor); b.CloseComponent(); }) ); // Now let's try changing the sorting var headerCell = grid.Find(".grid-header .sortable"); await grid.InvokeAsync(() => headerCell.Click()); Assert.AreEqual(2, grid.RenderCount); }
public void Does_Initial_Rendering() { ProviderDelegate <MyDto> provider = (r, _) => { return(ValueTask.FromResult(new BlazorGridResult <MyDto> { TotalCount = 1, Data = new List <MyDto> { new MyDto { Name = "Unit test" } } })); }; var grid = RenderComponent <BlazorGrid <MyDto> >( Parameter(nameof(BlazorGrid <MyDto> .Provider), provider), Template <MyDto>(nameof(ChildContent), (context) => (RenderTreeBuilder b) => { Expression <Func <string> > colFor = () => context.Name; b.OpenComponent <GridCol <string> >(0); b.AddAttribute(1, "For", colFor); b.CloseComponent(); }) ); Assert.AreEqual(1, grid.RenderCount); var virtualize = grid.FindComponent <Virtualize <MyDto> >(); Assert.AreEqual(1, virtualize.RenderCount); }
public Provider(ProviderDelegate provider) { if (provider == null) { throw new ArgumentNullException(nameof(provider)); } _provider = provider; }
public void Query_Triggers_Rerender() { ProviderDelegate <MyDto> provider = (r, _) => { return(ValueTask.FromResult(new BlazorGridResult <MyDto> { TotalCount = 1, Data = new List <MyDto> { new MyDto { Name = "Unit test" } } })); }; var grid = RenderComponent <BlazorGrid <MyDto> >( Parameter(nameof(BlazorGrid <MyDto> .Provider), provider), Template <MyDto>(nameof(ChildContent), (context) => (RenderTreeBuilder b) => { Expression <Func <string> > colFor = () => context.Name; b.OpenComponent <GridCol <string> >(0); b.AddAttribute(1, "For", colFor); b.CloseComponent(); }) ); // Now let's try changing the sorting var col = grid.FindComponent <GridCol <string> >(); grid.SetParametersAndRender( Parameter(nameof(BlazorGrid <MyDto> .QueryUserInput), "Hello world") ); // Since this property uses a debounce, there shouldn't be any render yet Assert.AreEqual(1, grid.RenderCount); // Wait for it... Task.Delay(500).Wait(); Assert.AreNotEqual(1, grid.RenderCount); }
public void Filter_Descriptor_Collection_Change_Triggers_Provider_Call() { int providerCallCount = 0; FilterDescriptor callFilterDescriptor = null; ProviderDelegate <MyDto> provider = (r, c) => { providerCallCount++; callFilterDescriptor = r.Filter; return(ValueTask.FromResult(new BlazorGridResult <MyDto> { Data = new List <MyDto>(), TotalCount = 0 })); }; var grid = RenderComponent <BlazorGrid <MyDto> >( Template <MyDto>(nameof(ChildContent), (dto) => (b) => { Expression <Func <string> > colFor = () => dto.Name; b.OpenComponent(0, typeof(GridCol <string>)); b.AddAttribute(1, nameof(GridCol <string> .Caption), nameof(dto.Name)); b.AddAttribute(2, nameof(GridCol <string> .For), colFor); b.CloseComponent(); }) ); Assert.AreEqual(1, providerCallCount); // Set a filter grid.Instance.Filter.Filters.Add(new PropertyFilter { Property = "Foo", Operator = FilterOperator.Contains, Value = "Bar" }); Assert.AreEqual(2, providerCallCount); Assert.IsNotNull(callFilterDescriptor); Assert.IsTrue(callFilterDescriptor.Filters.Any(x => x.Value == "Bar")); }
public void Can_Merge_Css_Classes() { int providerCallCount = 0; ProviderDelegate <MyDto> provider = (BlazorGridRequest r, CancellationToken c) => { providerCallCount++; return(ValueTask.FromResult(new BlazorGridResult <MyDto> { Data = Enumerable.Repeat(new MyDto(), 3).ToList(), TotalCount = 3 })); }; Services.AddSingleton <IBlazorGridConfig>(new Config.DefaultConfig()); Services.AddSingleton <NavigationManager>(new MockNav()); var row = new MyDto { Name = "Unit test" }; Expression <Func <string> > colFor = () => row.Name; var grid = RenderComponent <BlazorGrid <MyDto> >( Parameter(nameof(BlazorGrid <MyDto> .Provider), provider), Template <MyDto>(nameof(ChildContent), (context) => (RenderTreeBuilder builder) => { builder.OpenComponent <GridCol <string> >(0); builder.AddAttribute(1, nameof(GridCol <string> .For), colFor); builder.AddAttribute(2, "class", "my-custom-class"); builder.AddAttribute(3, nameof(GridCol <string> .AlignRight), true); builder.CloseComponent(); }) ); Assert.AreEqual(1, providerCallCount); var rowElement = grid.FindAll(".grid-row").Last(); rowElement.MarkupMatches("<div class=\"grid-row\"><div class=\"text-right my-custom-class\">Unit test</div></div>"); }
public void Can_Detect_Sorted_Column(bool desc) { int providerCallCount = 0; string providerCallOrderBy = null; bool? providerCallOrderByDescending = null; ProviderDelegate <MyDto> provider = (BlazorGridRequest r, CancellationToken c) => { providerCallCount++; providerCallOrderBy = r.OrderBy; providerCallOrderByDescending = r.OrderByDescending; return(ValueTask.FromResult(new BlazorGridResult <MyDto> { Data = Enumerable.Repeat(new MyDto(), 3).ToList(), TotalCount = 3 })); }; var grid = RenderComponent <BlazorGrid <MyDto> >( Parameter(nameof(BlazorGrid <MyDto> .Provider), provider), Parameter(nameof(BlazorGrid <MyDto> .DefaultOrderBy), (Expression <Func <MyDto, object> >)(x => x.Name)), Parameter(nameof(BlazorGrid <MyDto> .DefaultOrderByDescending), desc), Template <MyDto>(nameof(ChildContent), (dto) => b => { b.OpenComponent(0, typeof(GridCol <string>)); b.AddAttribute(1, nameof(GridCol <string> .For), (Expression <Func <string> >)(() => dto.Name)); b.CloseComponent(); }) ); Assert.AreEqual(1, providerCallCount); Assert.AreEqual(nameof(MyDto.Name), providerCallOrderBy); Assert.AreEqual(desc, providerCallOrderByDescending.Value); var th = grid.Find(".grid-header > *"); th.MarkupMatches("<div class=\"sorted sortable\"><span class=\"blazor-grid-sort-icon active " + (desc ? "sorted-desc" : "sorted-asc") + "\"></span></div>"); }
public async Task Header_Click_Triggers_Sort() { int providerCallCount = 0; string providerCallOrderBy = null; ProviderDelegate <MyDto> provider = (BlazorGridRequest r, CancellationToken c) => { providerCallCount++; providerCallOrderBy = r.OrderBy; return(ValueTask.FromResult(new BlazorGridResult <MyDto> { Data = Enumerable.Repeat(new MyDto(), 3).ToList(), TotalCount = 3 })); }; var grid = RenderComponent <BlazorGrid <MyDto> >( Parameter(nameof(BlazorGrid <MyDto> .Provider), provider), Template <MyDto>(nameof(ChildContent), (dto) => (b) => { b.OpenComponent(0, typeof(GridCol <string>)); b.AddAttribute(1, nameof(GridCol <string> .For), (Expression <Func <string> >)(() => dto.Name)); b.CloseComponent(); }) ); Assert.AreEqual(1, providerCallCount); Assert.IsNull(providerCallOrderBy); var th = grid.Find(".grid-header > *"); Assert.IsNotNull(th, "Failed to find the column header element"); await grid.InvokeAsync(() => th.Click()); Assert.AreEqual(2, providerCallCount); Assert.AreEqual(nameof(MyDto.Name), providerCallOrderBy); }
public void Filter_Descriptor_Property_Change_Triggers_Provider_Call() { int providerCallCount = 0; FilterDescriptor callFilterDescriptor = null; ProviderDelegate <MyDto> provider = (r, c) => { providerCallCount++; callFilterDescriptor = r.Filter; return(ValueTask.FromResult(new BlazorGridResult <MyDto> { Data = new List <MyDto>(), TotalCount = 0 })); }; var grid = RenderComponent <BlazorGrid <MyDto> >( Parameter(nameof(BlazorGrid <MyDto> .Provider), provider), Template <MyDto>(nameof(ChildContent), (dto) => (b) => { Expression <Func <string> > colFor = () => dto.Name; b.OpenComponent(0, typeof(GridCol <string>)); b.AddAttribute(1, nameof(GridCol <string> .Caption), nameof(MyDto.Name)); b.AddAttribute(2, nameof(GridCol <string> .For), colFor); b.CloseComponent(); }) ); // The initial request to the provider must have happened Assert.AreEqual(1, providerCallCount); grid.Instance.Filter.Connector = ConnectorType.Any; Assert.AreEqual(2, providerCallCount); Assert.IsNotNull(callFilterDescriptor); Assert.AreEqual(ConnectorType.Any, callFilterDescriptor.Connector); }
public async Task OnClick_Does_Not_Trigger_Rerender() { ProviderDelegate <MyDto> provider = (r, _) => { return(ValueTask.FromResult(new BlazorGridResult <MyDto> { TotalCount = 1, Data = new List <MyDto> { new MyDto { Name = "Unit test" } } })); }; var clickCount = 0; var grid = RenderComponent <BlazorGrid <MyDto> >( Parameter(nameof(BlazorGrid <MyDto> .Provider), provider), EventCallback <MyDto>(nameof(BlazorGrid <MyDto> .OnClick), _ => clickCount++), Template <MyDto>(nameof(ChildContent), (context) => (RenderTreeBuilder b) => { Expression <Func <string> > colFor = () => context.Name; b.OpenComponent <GridCol <string> >(0); b.AddAttribute(1, "For", colFor); b.CloseComponent(); }) ); // Try clicking on a row var row = grid.Find(".grid-row:not(.grid-header)"); await grid.InvokeAsync(() => row.Click()); Task.Delay(100).Wait(); Assert.AreEqual(1, grid.RenderCount); }
public static IHandler Provide(this IHandler handler, ProviderDelegate provider) { return(new Provider(provider) + handler); }
public async Task Retry_After_Error_Clears_Error() { int providerCallCount = 0; var styles = Services.GetRequiredService <IBlazorGridConfig>(); ProviderDelegate <MyDto> provider = (r, _) => { providerCallCount++; throw new Exception("unit test"); }; var grid = RenderComponent <BlazorGrid <MyDto> >( Parameter(nameof(BlazorGrid <MyDto> .Provider), provider), Template <MyDto>(nameof(ChildContent), (context) => (RenderTreeBuilder b) => { Expression <Func <string> > colFor = () => context.Name; b.OpenComponent <GridCol <string> >(0); b.AddAttribute(1, "For", colFor); b.CloseComponent(); }) ); Assert.AreEqual(1, providerCallCount); provider = (r, _) => { providerCallCount++; return(ValueTask.FromResult(new BlazorGridResult <MyDto> { TotalCount = 1, Data = new List <MyDto> { new MyDto { Name = "Mike" } } })); }; grid.SetParametersAndRender( Parameter(nameof(BlazorGrid <MyDto> .Provider), provider) ); // Verify that there is an error overlay var errorHeading = grid.Find(".grid-overlay ." + styles.Styles.ErrorHeadingClass.Replace(' ', '.')); Assert.IsNotNull(errorHeading); // Find the retry button var retryBtn = grid.Find(".grid-overlay ." + styles.Styles.ErrorFooterBtnClass.Replace(' ', '.')); Assert.IsNotNull(retryBtn); await grid.InvokeAsync(() => retryBtn.Click()); Assert.AreEqual(2, providerCallCount); try { grid.Find(".grid-overlay"); Assert.Fail(); } catch (ElementNotFoundException) { } }