bUnit icon indicating copy to clipboard operation
bUnit copied to clipboard

Investigate QuickGrid in .NET7

Open linkdotnet opened this issue 1 year ago • 4 comments

With the ASP.NET Core 7 Preview 6 announcements they also introduced QuickGrid as an external package. Even though this is not a first class citizen directly inside aspnet chances are lots of people will use it as a lightweight alternative to full blown grids. Currently it is flagged experimental. We should have an eye on that and make it was to setup in bUnit if it needs further setup.

Article: https://aspnet.github.io/quickgridsamples/

linkdotnet avatar Jul 15 '22 05:07 linkdotnet

Yeah, I was actually thinking of asking Steve if he wants a PR with bUnit tests for it. Don't think there is much JSInterop in there besides an init call, so should not be hard to support.

egil avatar Jul 17 '22 07:07 egil

No you are right, basically 2 to 3 Js calls, see here:

https://github.com/aspnet/AspLabs/blob/main/src/QuickGrid/src/Microsoft.AspNetCore.Components.QuickGrid/QuickGrid.razor.cs#L193

As this is an external package we don’t want to have this dependency in bUnit itself. I think a good example with explanation in the docs will be the way to go, what do you think ?

linkdotnet avatar Jul 17 '22 11:07 linkdotnet

I think a section in the docs about how to test a component that uses the QuickGrid component might be enough. My current thinking is that bUnit should not reference the QuickGrid package. If its turns out to be very complex to test with the QuickGrid component, then we could create a QuickGrid.bUnit package that folks can install.

egil avatar Jul 17 '22 14:07 egil

I wanted to tackle this and create a small section in the docs, but the alpha is really "alpha". For me the code snippets from the page are not working (getting compiler errors). Even after fixing them I get a blank screen. The grid element is in the DOM, but nothing gets displayed.

Lets at least wait until that goes into beta / RC before we tackle that. Right now the QuickGrid also doesn't get any new commits indicating not much active development.

linkdotnet avatar Aug 06 '22 07:08 linkdotnet

I will close this issue for the time being. The repo did not receive a commit in month and I also don’t think we have to do much (besides some JS mock calls). If we get a lot of user requests about this we can reopen the issue.

linkdotnet avatar Nov 15 '22 21:11 linkdotnet

Hi! So I've been trying out bUnit and testing and ran into an issue with setting up a test against a component that contains a quickgrid element, and I'm receiving an error that leads me to believe this just currently isn't supported in bUnit?

    Bunit.JSRuntimeUnhandledInvocationException: bUnit's JSInterop has not been configured to handle the call:

    InvokeAsync<IJSObjectReference>("import", "./_content/Microsoft.AspNetCore.Components.QuickGrid/QuickGrid.razor.js")

Based on this conversation is looks like it's pretty low priority. Are there any suggested workarounds that someone could try in the meantime? And the docs appear to list the quick grid package as reaching production with the release of .NET 8, is there a roadmap or plan to include support for any of the new features coming?

Dulatr avatar Aug 07 '23 21:08 Dulatr

Hey @Dulatr,

You should be good to go if you include the line reported by bUnit. If the whole topic becomes more relevant again, we might consider reopening the issue and taking action.

But, at least from my point of view, I am still with the picture given by @egil: As this is a 3rd party package (at least from the point of view of the .NET Framework), we don't want to import them directly. So either add a chapter to the documentation showing how to mock some JS-calls to make the QuickGrid work or offer an additional bUnit.QuickGrid package.

That depends on how hard it is to set up the whole thing. (Mocking three calls would not justify having the overhead of maintaining an additional package).

linkdotnet avatar Aug 08 '23 05:08 linkdotnet

I really appreciate the response. That makes sense.

I hope I'm not being a bother though but I'm still a little confused on how to setup JSInterop since it seems to be ignoring the any argument match on the init setup.

When configuring the calls I follow the error messages which state to setup the import:

TestContext!.JSInterop
    .SetupModule("./_content/Microsoft.AspNetCore.Components.QuickGrid/QuickGrid.razor.js");

After executing the tests again I receive the message that the other JS call is not setup:

    Bunit.JSRuntimeUnhandledInvocationException: bUnit's JSInterop has not been configured to handle the call:

    InvokeAsync<IJSObjectReference>("init", Microsoft.AspNetCore.Components.ElementReference)

Configure bUnit's JSInterop to handle the call with following:

    Setup<IJSObjectReference>("init", Microsoft.AspNetCore.Components.ElementReference)

or the following, to match any arguments:
    Setup<IJSObjectReference>("init", _ => true)

So I'm not sure how to get an element reference in order to call the first suggestion, so I chose to call the match for any argument:

TestContext!.JSInterop
	.SetupModule("./_content/Microsoft.AspNetCore.Components.QuickGrid/QuickGrid.razor.js")
	.Setup<QuickGrid<MyCoolDataType>>("init", _ => true);

Which rethrows the same exact error as above. I'm sure it's my general lack of understanding but I'm not sure what I'm missing. This is leading me to believe I need supply an element reference as the parameter but nothing seems to work when I try that as I'm not sure what the id or context would be, and I would assume the match to any arguments should catch this. So possibly the type for the QuickGrid item is not being matched correctly in that case?

Dulatr avatar Aug 08 '23 16:08 Dulatr

Hey @Dulatr,

yeah probably it makes sense to add something to our documentation. Basically an ElementReference is a handle to an HTML element. You might have seen the @ref attribute on certain HTML elements in the Blazor code.

@page "/"
@inject IJSRuntime JSRuntime
Enter your name
<input @ref=ReferenceToInputControl />

@code
{
    ElementReference ReferenceToInputControl;
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
            await JSRuntime.InvokeVoidAsync("MyJsCall", ReferenceToInputControl);
    }
}

In the case of the QuickGrid it wants a reference to the HTML table. Remember, the code comes from internal data structures and functions and does not necessarily has something to do with your user code.

The QuickGrid is "basically"I oversimplify here extremely an HTML table on steroids with fancy features.

Full circle to your case:

TestContext!.JSInterop
	.SetupModule("./_content/Microsoft.AspNetCore.Components.QuickGrid/QuickGrid.razor.js")
	.Setup<ElementReference>("init", _ => true);

should do the trick for you.

linkdotnet avatar Aug 08 '23 16:08 linkdotnet

PS: And obviously you don't bother us at all - that is why we have that "forum". More than willing to help you.

linkdotnet avatar Aug 08 '23 16:08 linkdotnet

Thanks so much! So I still have some issues with it but was able to just resolve it by setting the runtime mode to 'loose' (my current use case is very basic, but would like to simply mock the exact call rather than defaulting all of them).

The code as you have written did not really fix it for me :/ it remained giving me the same error that it was not configured. I still think there's a problem with the call being matched in this case due to the generic argument here, but I don't know how to find or provide more information so if I play with it some more and get it working through mocking the exact init call I'll post back here. Unless I misunderstood what you were indicating by using the ElementReference as the generic argument.

Thanks again for trying help out, I really appreciate what you guys are doing with this project and it's helping me learn a lot more about how Blazor works in general.

Dulatr avatar Aug 09 '23 22:08 Dulatr