From c60a5334c62dd0bb769e652076c34d0b50c8c34c Mon Sep 17 00:00:00 2001 From: Malcolm Smith <20709258+msmithNI@users.noreply.github.com> Date: Mon, 26 Feb 2024 17:55:49 -0600 Subject: [PATCH] Update NimbleBlazor NI.CSharp.Analyzers to v2.0.21 (with code fixes) (#1867) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Pull Request ## 🤨 Rationale - Update NimbleBlazor NI.CSharp.Analyzers to v2.0.21 (as Renovate started in [!1696](https://github.com/ni/nimble/pull/1696) ) - Add an `.editorconfig` that allows us to further customize rules/standards ([Microsoft docs](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/code-style-rule-options)). Most of the rules I have in this one were added based on the specific failed rules/ errors triggered for the Nimble Blazor code ## 👩‍💻 Implementation Most of the file diffs are from standardizing on file-scoped namespace declarations (as previously discussed with Meyer). I opted to disable these rules for the same of this PR, to keep the number of changes to review smaller: - Rules requiring pattern matching - Rules for [expression-bodied members](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/expression-bodied-members) - Rules covering ['var' preferences](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0007-ide0008) There were some additional spurious errors/warnings being triggered for our .razor.cs files, for which I included comments in the editorconfig. For reference, [the .editorconfig from the ASW repo root](https://dev.azure.com/ni/DevCentral/_git/ASW?path=%2F.editorconfig&_a=contents&version=GBmain) ## 🧪 Testing PR build, glanced over Blazor example app in Storybook. Release build in Visual Studio ## ✅ Checklist - [x] I have updated the project documentation to reflect my changes or determined no changes are needed. --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- ...-2f401368-17a1-4382-99d5-3eff4d6752dc.json | 7 + packages/nimble-blazor/.editorconfig | 56 ++ .../Examples/Demo.Client/Demo.Client.csproj | 2 +- .../Examples/Demo.Client/Program.cs | 1 - .../Examples/Demo.Hybrid/App.xaml.cs | 17 +- .../Examples/Demo.Hybrid/Demo.Hybrid.csproj | 2 +- .../Examples/Demo.Hybrid/MainWindow.xaml.cs | 55 +- .../Examples/Demo.Server/Demo.Server.csproj | 2 +- .../Demo.Server/Pages/Error.cshtml.cs | 30 +- .../Examples/Demo.Shared/Demo.Shared.csproj | 2 +- .../Demo.Shared/Pages/ComponentsDemo.razor.cs | 505 +++++++++--------- .../Demo.Shared/Shared/ExampleHeader.razor.cs | 67 ++- .../Demo.Shared/Shared/MainLayout.razor.cs | 27 +- .../Components/NimbleDialog.razor.cs | 4 +- .../Components/NimbleDrawer.razor.cs | 4 +- .../Components/NimbleRadio.razor.cs | 3 +- .../Components/NimbleTable.razor.cs | 5 +- .../Components/NimbleWaferMap.razor.cs | 18 +- .../NimbleBlazor/DateTextColumnTypes.cs | 20 +- .../NimbleBlazor/EventHandlers.cs | 3 +- .../NimbleBlazor/NimbleBlazor.csproj | 2 +- .../NimbleBlazor/NimbleInputBase.cs | 4 +- .../NimbleBlazor/NimbleMappingBase.cs | 2 + .../NimbleBlazor.Tests.Acceptance.csproj | 2 +- .../PlaywrightFixture.cs | 1 - .../NimbleBlazor.Tests.Acceptance/Program.cs | 29 +- .../Shared/MainLayout.razor.cs | 28 +- .../SharedPlaywrightCollectionDefinition.cs | 15 +- .../Tests/AcceptanceTestsBase.cs | 85 ++- .../Tests/DialogTests.cs | 45 +- .../Tests/DrawerTests.cs | 45 +- .../Tests/TableColumnEnumTextTests.cs | 33 +- .../Tests/TableColumnIconTests.cs | 37 +- .../Tests/TableColumnNumberTextTests.cs | 33 +- .../Tests/TableTests.cs | 130 ++--- .../Tests/ThemeProviderTests.cs | 43 +- .../Tests/WaferMapTests.cs | 103 ++-- .../NimbleBlazor.Tests.csproj | 2 +- .../Components/NimbleAnchorButtonTests.cs | 1 - .../Unit/Components/NimbleTableTests.cs | 20 +- 40 files changed, 763 insertions(+), 727 deletions(-) create mode 100644 change/@ni-nimble-blazor-2f401368-17a1-4382-99d5-3eff4d6752dc.json create mode 100644 packages/nimble-blazor/.editorconfig diff --git a/change/@ni-nimble-blazor-2f401368-17a1-4382-99d5-3eff4d6752dc.json b/change/@ni-nimble-blazor-2f401368-17a1-4382-99d5-3eff4d6752dc.json new file mode 100644 index 0000000000..849c5b0e44 --- /dev/null +++ b/change/@ni-nimble-blazor-2f401368-17a1-4382-99d5-3eff4d6752dc.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Uptake new code analyzer rules, minor code cleanup", + "packageName": "@ni/nimble-blazor", + "email": "20709258+msmithNI@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/packages/nimble-blazor/.editorconfig b/packages/nimble-blazor/.editorconfig new file mode 100644 index 0000000000..609d7cf63b --- /dev/null +++ b/packages/nimble-blazor/.editorconfig @@ -0,0 +1,56 @@ +[*.cs] + +csharp_style_namespace_declarations = file_scoped:warning +csharp_prefer_simple_using_statement = false +dotnet_style_prefer_conditional_expression_over_return = false + +# Disable: Remove unnecessary expression value (_/discard not required) +dotnet_diagnostic.IDE0058.severity = none + +# Rules for the use of 'var': +dotnet_diagnostic.IDE0007.severity = none +dotnet_diagnostic.IDE0008.severity = none +# Note: ASW generally uses the settings below, may opt in in the future. +# csharp_style_var_for_built_in_types = false +# csharp_style_var_when_type_is_apparent = true +# csharp_style_var_elsewhere = false + +# Expression-bodied members +# Note: May switch to when_on_single_line for methods/properties/accessors +# in the future +# csharp_style_expression_bodied_methods +dotnet_diagnostic.IDE0022.severity = none +# csharp_style_expression_bodied_properties +dotnet_diagnostic.IDE0025.severity = none +# csharp_style_expression_bodied_indexers +dotnet_diagnostic.IDE0026.severity = none +# csharp_style_expression_bodied_accessors +dotnet_diagnostic.IDE0027.severity = none + +# Use 'switch' expression +dotnet_diagnostic.IDE0066.severity = none + +# Pattern matching +# Disable general pattern matching rule for now, may opt in in the future +dotnet_diagnostic.IDE0078.severity = none + +[*.razor.cs] +# Spurious 'unused' warnings when properties/methods are only used from Razor files +dotnet_diagnostic.IDE0051.severity = none +dotnet_diagnostic.IDE0052.severity = none +# 'Make field readonly' incorrectly triggered for component _refs +dotnet_diagnostic.IDE0044.severity = none + +[Program.cs] +# Spurious 'unnecessary using' warnings +dotnet_diagnostic.IDE0005.severity = none + +[Tests/NimbleBlazor.Tests.Acceptance/Tests/*.cs] +dotnet_style_namespace_match_folder = false +# Disable 'Namespace does not match folder structure' +dotnet_diagnostic.IDE0130.severity = none + +[Examples/Demo.Shared/Shared/*.cs] +dotnet_style_namespace_match_folder = false +# Disable 'Namespace does not match folder structure' +dotnet_diagnostic.IDE0130.severity = none \ No newline at end of file diff --git a/packages/nimble-blazor/Examples/Demo.Client/Demo.Client.csproj b/packages/nimble-blazor/Examples/Demo.Client/Demo.Client.csproj index 03dd4b1b94..d33105e345 100644 --- a/packages/nimble-blazor/Examples/Demo.Client/Demo.Client.csproj +++ b/packages/nimble-blazor/Examples/Demo.Client/Demo.Client.csproj @@ -24,7 +24,7 @@ - + diff --git a/packages/nimble-blazor/Examples/Demo.Client/Program.cs b/packages/nimble-blazor/Examples/Demo.Client/Program.cs index 1499f7e372..9b7bc78352 100644 --- a/packages/nimble-blazor/Examples/Demo.Client/Program.cs +++ b/packages/nimble-blazor/Examples/Demo.Client/Program.cs @@ -1,4 +1,3 @@ -#pragma warning disable CA1812 using Demo.Shared; using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; diff --git a/packages/nimble-blazor/Examples/Demo.Hybrid/App.xaml.cs b/packages/nimble-blazor/Examples/Demo.Hybrid/App.xaml.cs index c2773ef781..7deee2e3db 100644 --- a/packages/nimble-blazor/Examples/Demo.Hybrid/App.xaml.cs +++ b/packages/nimble-blazor/Examples/Demo.Hybrid/App.xaml.cs @@ -1,11 +1,10 @@ -namespace Demo.Hybrid -{ - using System.Windows; +using System.Windows; + +namespace Demo.Hybrid; - /// - /// Interaction logic for App.xaml. - /// - public partial class App : Application - { - } +/// +/// Interaction logic for App.xaml. +/// +public partial class App : Application +{ } diff --git a/packages/nimble-blazor/Examples/Demo.Hybrid/Demo.Hybrid.csproj b/packages/nimble-blazor/Examples/Demo.Hybrid/Demo.Hybrid.csproj index 3fd4de95f6..1282cf1df8 100644 --- a/packages/nimble-blazor/Examples/Demo.Hybrid/Demo.Hybrid.csproj +++ b/packages/nimble-blazor/Examples/Demo.Hybrid/Demo.Hybrid.csproj @@ -18,7 +18,7 @@ - + diff --git a/packages/nimble-blazor/Examples/Demo.Hybrid/MainWindow.xaml.cs b/packages/nimble-blazor/Examples/Demo.Hybrid/MainWindow.xaml.cs index 456173a5c0..ec3dd5498c 100644 --- a/packages/nimble-blazor/Examples/Demo.Hybrid/MainWindow.xaml.cs +++ b/packages/nimble-blazor/Examples/Demo.Hybrid/MainWindow.xaml.cs @@ -1,41 +1,38 @@ -namespace Demo.Hybrid -{ - using System.Windows; - using Microsoft.Extensions.DependencyInjection; +using System.Windows; +using Microsoft.Extensions.DependencyInjection; + +namespace Demo.Hybrid; +/// +/// Interaction logic for MainWindow.xaml. +/// +public partial class MainWindow : Window +{ /// - /// Interaction logic for MainWindow.xaml. + /// Initializes a new instance of the class. /// - public partial class MainWindow : Window + public MainWindow() { - /// - /// Initializes a new instance of the class. - /// - public MainWindow() - { - this.InitializeComponent(); + InitializeComponent(); #if RELEASE - this.Loaded += this.MainWindow_Loaded; + Loaded += MainWindow_Loaded; #endif - var serviceCollection = new ServiceCollection(); - serviceCollection.AddWpfBlazorWebView(); - serviceCollection.AddBlazorWebViewDeveloperTools(); -#pragma warning disable NI1004 - this.Resources.Add("services", serviceCollection.BuildServiceProvider()); -#pragma warning restore NI1004 - } + var serviceCollection = new ServiceCollection(); + serviceCollection.AddWpfBlazorWebView(); + serviceCollection.AddBlazorWebViewDeveloperTools(); + Resources.Add("services", serviceCollection.BuildServiceProvider()); + } #if RELEASE #pragma warning disable VSTHRD100 // Avoid async void methods - private async void MainWindow_Loaded(object sender, RoutedEventArgs e) + private async void MainWindow_Loaded(object sender, RoutedEventArgs e) #pragma warning restore VSTHRD100 // Avoid async void methods - { - // We recommend for Release versions to turn off browser accelerator keys - // for applications that are meant to operate more like a native desktop app. - await this.blazorWebView.WebView.EnsureCoreWebView2Async().ConfigureAwait(true); - var settings = this.blazorWebView.WebView.CoreWebView2.Settings; - settings.AreBrowserAcceleratorKeysEnabled = false; - } -#endif + { + // We recommend for Release versions to turn off browser accelerator keys + // for applications that are meant to operate more like a native desktop app. + await blazorWebView.WebView.EnsureCoreWebView2Async().ConfigureAwait(true); + var settings = blazorWebView.WebView.CoreWebView2.Settings; + settings.AreBrowserAcceleratorKeysEnabled = false; } +#endif } diff --git a/packages/nimble-blazor/Examples/Demo.Server/Demo.Server.csproj b/packages/nimble-blazor/Examples/Demo.Server/Demo.Server.csproj index 9c55b97c80..0f0c3d1e97 100644 --- a/packages/nimble-blazor/Examples/Demo.Server/Demo.Server.csproj +++ b/packages/nimble-blazor/Examples/Demo.Server/Demo.Server.csproj @@ -19,7 +19,7 @@ - + diff --git a/packages/nimble-blazor/Examples/Demo.Server/Pages/Error.cshtml.cs b/packages/nimble-blazor/Examples/Demo.Server/Pages/Error.cshtml.cs index 3c3b7b7894..cd746b5cbb 100644 --- a/packages/nimble-blazor/Examples/Demo.Server/Pages/Error.cshtml.cs +++ b/packages/nimble-blazor/Examples/Demo.Server/Pages/Error.cshtml.cs @@ -2,26 +2,22 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; -namespace Demo.Server.Pages -{ - [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] - [IgnoreAntiforgeryToken] - public class ErrorModel : PageModel - { - private readonly ILogger _logger; +namespace Demo.Server.Pages; - public string? RequestId { get; set; } +[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] +[IgnoreAntiforgeryToken] +public class ErrorModel : PageModel +{ + public string? RequestId { get; set; } - public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); - public ErrorModel(ILogger logger) - { - _logger = logger; - } + public ErrorModel() + { + } - public void OnGet() - { - RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; - } + public void OnGet() + { + RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; } } \ No newline at end of file diff --git a/packages/nimble-blazor/Examples/Demo.Shared/Demo.Shared.csproj b/packages/nimble-blazor/Examples/Demo.Shared/Demo.Shared.csproj index 1c58e7fbc9..b5ae12ed1a 100644 --- a/packages/nimble-blazor/Examples/Demo.Shared/Demo.Shared.csproj +++ b/packages/nimble-blazor/Examples/Demo.Shared/Demo.Shared.csproj @@ -20,7 +20,7 @@ - + diff --git a/packages/nimble-blazor/Examples/Demo.Shared/Pages/ComponentsDemo.razor.cs b/packages/nimble-blazor/Examples/Demo.Shared/Pages/ComponentsDemo.razor.cs index 3645f45127..90bc666064 100644 --- a/packages/nimble-blazor/Examples/Demo.Shared/Pages/ComponentsDemo.razor.cs +++ b/packages/nimble-blazor/Examples/Demo.Shared/Pages/ComponentsDemo.razor.cs @@ -2,304 +2,303 @@ using System.Globalization; using NimbleBlazor; -namespace Demo.Shared.Pages +namespace Demo.Shared.Pages; + +/// +/// The components demo page +/// +public partial class ComponentsDemo { - /// - /// The components demo page - /// - public partial class ComponentsDemo + private DrawerLocation _drawerLocation = DrawerLocation.Right; + private string? ActiveTabId { get; set; } + private string? ActiveAnchorTabId { get; set; } = "a-tab-1"; + private NimbleDialog? _dialog; + private string? DialogClosedReason { get; set; } + private NimbleDrawer? _drawer; + private NimbleTable? _table; + private NimbleTable? _delayedHierarchyTable; + private string? DrawerClosedReason { get; set; } + private string? SelectedRadio { get; set; } = "2"; + private bool BannerOpen { get; set; } + private readonly List _delayedHierarchyTableData = new() { - private DrawerLocation _drawerLocation = DrawerLocation.Right; - private string? ActiveTabId { get; set; } - private string? ActiveAnchorTabId { get; set; } = "a-tab-1"; - private NimbleDialog? _dialog; - private string? DialogClosedReason { get; set; } - private NimbleDrawer? _drawer; - private NimbleTable? _table; - private NimbleTable? _delayedHierarchyTable; - private string? DrawerClosedReason { get; set; } - private string? SelectedRadio { get; set; } = "2"; - private bool BannerOpen { get; set; } - private List _delayedHierarchyTableData = new List() - { - new PersonTableRecord("jacqueline-bouvier", null, "Jacqueline", "Bouvier", 80, true), - new PersonTableRecord("mona-simpson", null, "Mona", "Simpson", 77, true), - new PersonTableRecord("agnes-skinner", null, "Agnes", "Skinner", 88, true) - }; - private HashSet _recordsLoadingChildren = new HashSet(); - private HashSet _recordsWithLoadedChildren = new HashSet(); + new PersonTableRecord("jacqueline-bouvier", null, "Jacqueline", "Bouvier", 80, true), + new PersonTableRecord("mona-simpson", null, "Mona", "Simpson", 77, true), + new PersonTableRecord("agnes-skinner", null, "Agnes", "Skinner", 88, true) + }; + private readonly HashSet _recordsLoadingChildren = new(); + private readonly HashSet _recordsWithLoadedChildren = new(); - [NotNull] - public IEnumerable TableData { get; set; } = Enumerable.Empty(); - [NotNull] - public IEnumerable Dies { get; set; } = Enumerable.Empty(); - [NotNull] - public IEnumerable HighlightedTags { get; set; } = Enumerable.Empty(); - [NotNull] - public WaferMapColorScale ColorScale { get; set; } = new WaferMapColorScale(new List { "red", "green" }, new List { "0", "100" }); + [NotNull] + public IEnumerable TableData { get; set; } = Enumerable.Empty(); + [NotNull] + public IEnumerable Dies { get; set; } = Enumerable.Empty(); + [NotNull] + public IEnumerable HighlightedTags { get; set; } = Enumerable.Empty(); + [NotNull] + public WaferMapColorScale ColorScale { get; set; } = new WaferMapColorScale(new List { "red", "green" }, new List { "0", "100" }); - public ComponentsDemo() - { - AddTableRows(10); - UpdateDies(5); - } + public ComponentsDemo() + { + AddTableRows(10); + UpdateDies(5); + } - protected override async Task OnAfterRenderAsync(bool firstRender) + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await _table!.SetDataAsync(TableData); + await UpdateDelayedHierarchyTableAsync(); + await base.OnAfterRenderAsync(firstRender); + } + + private async Task OnRowExpandToggleAsync(TableRowExpandToggleEventArgs e) + { + var recordId = e.RecordId; + if (e.NewState && !_recordsLoadingChildren.Contains(recordId) && !_recordsWithLoadedChildren.Contains(recordId)) { - await _table!.SetDataAsync(TableData); + var record = _delayedHierarchyTableData.Find(person => person.Id == recordId); + if (record == null) + { + return; + } + + _recordsLoadingChildren.Add(recordId); + await UpdateDelayedHierarchyTableAsync(false); + + await Task.Delay(1500); + _recordsLoadingChildren.Remove(recordId); + _recordsWithLoadedChildren.Add(recordId); + var childrenToAdd = GetChildren(recordId); + childrenToAdd.ForEach(child => _delayedHierarchyTableData.Add(child)); await UpdateDelayedHierarchyTableAsync(); - await base.OnAfterRenderAsync(firstRender); } + } - private async Task OnRowExpandToggleAsync(TableRowExpandToggleEventArgs e) + private List GetChildren(string recordId) + { + switch (recordId) { - var recordId = e.RecordId; - if (e.NewState && !_recordsLoadingChildren.Contains(recordId) && !_recordsWithLoadedChildren.Contains(recordId)) - { - var record = _delayedHierarchyTableData.Find(person => person.Id == recordId); - if (record == null) + case "jacqueline-bouvier": + return new List() { - return; - } - - _recordsLoadingChildren.Add(recordId); - await UpdateDelayedHierarchyTableAsync(false); - - await Task.Delay(1500); - _recordsLoadingChildren.Remove(recordId); - _recordsWithLoadedChildren.Add(recordId); - var childrenToAdd = GetChildren(recordId); - childrenToAdd.ForEach(child => _delayedHierarchyTableData.Add(child)); - await UpdateDelayedHierarchyTableAsync(); - } + new PersonTableRecord("marge-simpson", recordId, "Marge", "Simpson", 35, true), + new PersonTableRecord("selma-bouvier", recordId, "Selma", "Bouvier", 45, false), + new PersonTableRecord("patty-bouvier", recordId, "Patty", "Bouvier", 45, false) + }; + case "marge-simpson": + return new List() + { + new PersonTableRecord("bart-simpson", recordId, "Bart", "Simpson", 12, false), + new PersonTableRecord("lisa-bouvier", recordId, "Lisa", "Simpson", 10, false), + new PersonTableRecord("maggie-bouvier", recordId, "Maggie", "Simpson", 1, false) + }; + case "mona-simpson": + return new List() + { + new PersonTableRecord("homer-simpson", recordId, "Homer", "Simpson", 35, false) + }; + case "agnes-skinner": + return new List() + { + new PersonTableRecord("seymour-skinner", recordId, "Seymour", "Skinner", 42, false) + }; + default: + return new List(); } + } - private List GetChildren(string recordId) + private async Task UpdateDelayedHierarchyTableAsync(bool setData = true) + { + if (setData) { - switch (recordId) - { - case "jacqueline-bouvier": - return new List() - { - new PersonTableRecord("marge-simpson", recordId, "Marge", "Simpson", 35, true), - new PersonTableRecord("selma-bouvier", recordId, "Selma", "Bouvier", 45, false), - new PersonTableRecord("patty-bouvier", recordId, "Patty", "Bouvier", 45, false) - }; - case "marge-simpson": - return new List() - { - new PersonTableRecord("bart-simpson", recordId, "Bart", "Simpson", 12, false), - new PersonTableRecord("lisa-bouvier", recordId, "Lisa", "Simpson", 10, false), - new PersonTableRecord("maggie-bouvier", recordId, "Maggie", "Simpson", 1, false) - }; - case "mona-simpson": - return new List() - { - new PersonTableRecord("homer-simpson", recordId, "Homer", "Simpson", 35, false) - }; - case "agnes-skinner": - return new List() - { - new PersonTableRecord("seymour-skinner", recordId, "Seymour", "Skinner", 42, false) - }; - default: - return new List(); - } + await _delayedHierarchyTable!.SetDataAsync(_delayedHierarchyTableData); } - private async Task UpdateDelayedHierarchyTableAsync(bool setData = true) + List options = new(); + _delayedHierarchyTableData.ForEach(person => { - if (setData) + if (_recordsLoadingChildren.Contains(person.Id)) { - await _delayedHierarchyTable!.SetDataAsync(_delayedHierarchyTableData); + options.Add( + new TableSetRecordHierarchyOptions( + person.Id, + new TableRecordHierarchyOptions(TableRecordDelayedHierarchyState.LoadingChildren))); } - - List options = new List(); - _delayedHierarchyTableData.ForEach(person => + else if (person.HasChildren && !_recordsWithLoadedChildren.Contains(person.Id)) { - if (_recordsLoadingChildren.Contains(person.Id)) - { - options.Add( - new TableSetRecordHierarchyOptions( - person.Id, - new TableRecordHierarchyOptions(TableRecordDelayedHierarchyState.LoadingChildren))); - } - else if (person.HasChildren && !_recordsWithLoadedChildren.Contains(person.Id)) - { - options.Add( - new TableSetRecordHierarchyOptions( - person.Id, - new TableRecordHierarchyOptions(TableRecordDelayedHierarchyState.CanLoadChildren))); - } - }); - await _delayedHierarchyTable!.SetRecordHierarchyOptionsAsync(options); - } + options.Add( + new TableSetRecordHierarchyOptions( + person.Id, + new TableRecordHierarchyOptions(TableRecordDelayedHierarchyState.CanLoadChildren))); + } + }); + await _delayedHierarchyTable!.SetRecordHierarchyOptionsAsync(options); + } - private string DrawerLocationAsString - { - get => _drawerLocation.ToString(); - set => _drawerLocation = (DrawerLocation)Enum.Parse(typeof(DrawerLocation), value); - } + private string DrawerLocationAsString + { + get => _drawerLocation.ToString(); + set => _drawerLocation = (DrawerLocation)Enum.Parse(typeof(DrawerLocation), value); + } - public async Task OpenDialogAsync() - { - var response = await _dialog!.ShowAsync(); - DialogClosedReason = response.Reason == DialogCloseReason.UserDismissed ? "User dismissed" - : response.Value.ToString(); - } + public async Task OpenDialogAsync() + { + var response = await _dialog!.ShowAsync(); + DialogClosedReason = response.Reason == DialogCloseReason.UserDismissed ? "User dismissed" + : response.Value.ToString(); + } - public async Task CloseDialogAsync(DialogResult reason) - { - await _dialog!.CloseAsync(reason); - } + public async Task CloseDialogAsync(DialogResult reason) + { + await _dialog!.CloseAsync(reason); + } - public async Task OpenDrawerAsync() - { - var response = await _drawer!.ShowAsync(); - DrawerClosedReason = response.Reason == DrawerCloseReason.UserDismissed ? "User dismissed" - : response.Value.ToString(); - } + public async Task OpenDrawerAsync() + { + var response = await _drawer!.ShowAsync(); + DrawerClosedReason = response.Reason == DrawerCloseReason.UserDismissed ? "User dismissed" + : response.Value.ToString(); + } - public async Task CloseDrawerAsync(DialogResult reason) - { - await _drawer!.CloseAsync(reason); - } + public async Task CloseDrawerAsync(DialogResult reason) + { + await _drawer!.CloseAsync(reason); + } + + public void AddTableRows(int numberOfRowsToAdd) + { + var tableData = new List(TableData); - public void AddTableRows(int numberOfRowsToAdd) + for (int i = 0; i < numberOfRowsToAdd; i++) { - var tableData = new List(TableData); + int rowCount = tableData.Count; + string rowCountString = rowCount.ToString(CultureInfo.CurrentCulture); - for (int i = 0; i < numberOfRowsToAdd; i++) - { - int rowCount = tableData.Count; - string rowCountString = rowCount.ToString(CultureInfo.CurrentCulture); + tableData.Add(new SimpleTableRecord( + rowCountString, + tableData.Count >= 4 ? (tableData.Count % 4).ToString(CultureInfo.CurrentCulture) : null, + $"new string {rowCountString}", + $"bar {rowCountString}", + "/", + "Link", + (rowCount % 2 == 0) ? new DateTime(2023, 8, 16, 2, 56, 11) : new DateTime(2022, 3, 7, 20, 28, 41), + (rowCount % 2 == 0) ? 100 : 101, + (rowCount % 2 == 0) ? "success" : "unknown", + rowCount / 10.0, + rowCount * 1000.0 * (1.1 + (2 * 60) + (3 * 3600)))); + } - tableData.Add(new SimpleTableRecord( - rowCountString, - tableData.Count >= 4 ? (tableData.Count % 4).ToString(CultureInfo.CurrentCulture) : null, - $"new string {rowCountString}", - $"bar {rowCountString}", - "/", - "Link", - (rowCount % 2 == 0) ? new DateTime(2023, 8, 16, 2, 56, 11) : new DateTime(2022, 3, 7, 20, 28, 41), - (rowCount % 2 == 0) ? 100 : 101, - (rowCount % 2 == 0) ? "success" : "unknown", - rowCount / 10.0, - rowCount * 1000.0 * (1.1 + 2 * 60 + 3 * 3600))); - } + TableData = tableData; + } - TableData = tableData; + public void UpdateDies(int numberOfDies) + { + if (numberOfDies < 0) + { + return; } + var dies = new List(); + int radius = (int)Math.Ceiling(Math.Sqrt(numberOfDies / Math.PI)); + var centerX = radius; + var centerY = radius; - public void UpdateDies(int numberOfDies) + for (var i = centerY - radius; i <= centerY + radius; i++) { - if (numberOfDies < 0) + for ( + var j = centerX; + ((j - centerX) * (j - centerX)) + ((i - centerY) * (i - centerY)) + <= radius * radius; + j--) { - return; + var value = (i + j) % 100; + dies.Add(new WaferMapDie(i, j, value.ToString(CultureInfo.CurrentCulture))); } - var dies = new List(); - int radius = (int)Math.Ceiling(Math.Sqrt(numberOfDies / Math.PI)); - var centerX = radius; - var centerY = radius; - - for (var i = centerY - radius; i <= centerY + radius; i++) + // generate points right of centerX + for ( + var j = centerX + 1; + ((j - centerX) * (j - centerX)) + ((i - centerY) * (i - centerY)) + <= radius * radius; + j++) { - for ( - var j = centerX; - (j - centerX) * (j - centerX) + (i - centerY) * (i - centerY) - <= radius * radius; - j--) - { - var value = (i + j) % 100; - dies.Add(new WaferMapDie(i, j, value.ToString(CultureInfo.CurrentCulture))); - } - // generate points right of centerX - for ( - var j = centerX + 1; - (j - centerX) * (j - centerX) + (i - centerY) * (i - centerY) - <= radius * radius; - j++) - { - var value = (i + j) % 100; - dies.Add(new WaferMapDie(i, j, value.ToString(CultureInfo.CurrentCulture))); - } + var value = (i + j) % 100; + dies.Add(new WaferMapDie(i, j, value.ToString(CultureInfo.CurrentCulture))); } - Dies = dies; - } - public void AddDiesToRadius(int numberOfDies) - { - UpdateDies(Dies.Count() + (int)(numberOfDies * numberOfDies * Math.PI)); - } - public void RemoveDiesFromRadius(int numberOfDies) - { - UpdateDies(Dies.Count() - (int)(numberOfDies * numberOfDies * Math.PI)); } + Dies = dies; } - - public class SimpleTableRecord + public void AddDiesToRadius(int numberOfDies) { - public SimpleTableRecord( - string id, - string? parentId, - string stringValue1, - string stringValue2, - string? href, - string? linkLabel, - DateTime date, - int statusCode, - string result, - double number, - double duration) - { - Id = id; - ParentId = parentId; - StringValue1 = stringValue1; - StringValue2 = stringValue2; - Href = href; - LinkLabel = linkLabel; - Date = (ulong)(date - DateTime.UnixEpoch.ToLocalTime()).TotalMilliseconds; - StatusCode = statusCode; - Result = result; - Number = number; - Duration = duration; - } - - public string Id { get; } - public string? ParentId { get; } - public string StringValue1 { get; } - public string StringValue2 { get; } - public string? Href { get; } - public string? LinkLabel { get; } - public ulong Date { get; } - public int StatusCode { get; } - public string Result { get; } - public double Number { get; } - public double Duration { get; } + UpdateDies(Dies.Count() + (int)(numberOfDies * numberOfDies * Math.PI)); } - - public class PersonTableRecord + public void RemoveDiesFromRadius(int numberOfDies) { - public PersonTableRecord(string id, string? parentId, string firstName, string lastName, int age, bool hasChildren) - { - Id = id; - ParentId = parentId; - FirstName = firstName; - LastName = lastName; - Age = age; - HasChildren = hasChildren; - } + UpdateDies(Dies.Count() - (int)(numberOfDies * numberOfDies * Math.PI)); + } +} - public string Id { get; } - public string? ParentId { get; } - public string FirstName { get; } - public string LastName { get; } - public int Age { get; } - public bool HasChildren { get; } +public class SimpleTableRecord +{ + public SimpleTableRecord( + string id, + string? parentId, + string stringValue1, + string stringValue2, + string? href, + string? linkLabel, + DateTime date, + int statusCode, + string result, + double number, + double duration) + { + Id = id; + ParentId = parentId; + StringValue1 = stringValue1; + StringValue2 = stringValue2; + Href = href; + LinkLabel = linkLabel; + Date = (ulong)(date - DateTime.UnixEpoch.ToLocalTime()).TotalMilliseconds; + StatusCode = statusCode; + Result = result; + Number = number; + Duration = duration; } - public enum DialogResult + public string Id { get; } + public string? ParentId { get; } + public string StringValue1 { get; } + public string StringValue2 { get; } + public string? Href { get; } + public string? LinkLabel { get; } + public ulong Date { get; } + public int StatusCode { get; } + public string Result { get; } + public double Number { get; } + public double Duration { get; } +} + +public class PersonTableRecord +{ + public PersonTableRecord(string id, string? parentId, string firstName, string lastName, int age, bool hasChildren) { - OK, - Cancel + Id = id; + ParentId = parentId; + FirstName = firstName; + LastName = lastName; + Age = age; + HasChildren = hasChildren; } + + public string Id { get; } + public string? ParentId { get; } + public string FirstName { get; } + public string LastName { get; } + public int Age { get; } + public bool HasChildren { get; } +} + +public enum DialogResult +{ + OK, + Cancel } diff --git a/packages/nimble-blazor/Examples/Demo.Shared/Shared/ExampleHeader.razor.cs b/packages/nimble-blazor/Examples/Demo.Shared/Shared/ExampleHeader.razor.cs index 69bc3722aa..2a55afa672 100644 --- a/packages/nimble-blazor/Examples/Demo.Shared/Shared/ExampleHeader.razor.cs +++ b/packages/nimble-blazor/Examples/Demo.Shared/Shared/ExampleHeader.razor.cs @@ -1,41 +1,40 @@ using Microsoft.AspNetCore.Components; using NimbleBlazor; -namespace Demo.Shared +namespace Demo.Shared; + +/// +/// The ExampleHeader Component. +/// +public partial class ExampleHeader { - /// - /// The ExampleHeader Component. - /// - public partial class ExampleHeader + private NimbleDrawer? _drawerReference; + + [Parameter] + public Theme Theme { get; set; } + + [Parameter] + public EventCallback ThemeChanged { get; set; } + + private string ThemeAsString + { + get => Theme.ToString(); + set => Theme = (Theme)Enum.Parse(typeof(Theme), value); + } + + private async void OnUserThemeChange(string newTheme) + { + ThemeAsString = newTheme; + await ThemeChanged.InvokeAsync(Theme); + } + + private async void OnUserSettingsSelected() + { + await _drawerReference!.ShowAsync(); + } + + private async void OnCloseButtonClicked() { - private NimbleDrawer? _drawerReference; - - [Parameter] - public Theme Theme { get; set; } - - [Parameter] - public EventCallback ThemeChanged { get; set; } - - private string ThemeAsString - { - get => Theme.ToString(); - set => Theme = (Theme)Enum.Parse(typeof(Theme), value); - } - - private async void OnUserThemeChange(string newTheme) - { - ThemeAsString = newTheme; - await ThemeChanged.InvokeAsync(Theme); - } - - private async void OnUserSettingsSelected() - { - await _drawerReference!.ShowAsync(); - } - - private async void OnCloseButtonClicked() - { - await _drawerReference!.CloseAsync(); - } + await _drawerReference!.CloseAsync(); } } \ No newline at end of file diff --git a/packages/nimble-blazor/Examples/Demo.Shared/Shared/MainLayout.razor.cs b/packages/nimble-blazor/Examples/Demo.Shared/Shared/MainLayout.razor.cs index fdf5ea884a..829a959dd7 100644 --- a/packages/nimble-blazor/Examples/Demo.Shared/Shared/MainLayout.razor.cs +++ b/packages/nimble-blazor/Examples/Demo.Shared/Shared/MainLayout.razor.cs @@ -3,23 +3,22 @@ using Microsoft.JSInterop; using NimbleBlazor; -namespace Demo.Shared +namespace Demo.Shared; + +/// +/// The MainLayout Component. +/// +public partial class MainLayout { - /// - /// The MainLayout Component. - /// - public partial class MainLayout - { - private Theme Theme { get; set; } = Theme.Light; + private Theme Theme { get; set; } = Theme.Light; - public ErrorBoundary? ErrorBoundary { get; set; } + public ErrorBoundary? ErrorBoundary { get; set; } - [Inject] - public IJSRuntime? JSRuntime { get; set; } + [Inject] + public IJSRuntime? JSRuntime { get; set; } - protected override void OnParametersSet() - { - ErrorBoundary?.Recover(); - } + protected override void OnParametersSet() + { + ErrorBoundary?.Recover(); } } \ No newline at end of file diff --git a/packages/nimble-blazor/NimbleBlazor/Components/NimbleDialog.razor.cs b/packages/nimble-blazor/NimbleBlazor/Components/NimbleDialog.razor.cs index 35d1e6cc06..c6b2f006ef 100644 --- a/packages/nimble-blazor/NimbleBlazor/Components/NimbleDialog.razor.cs +++ b/packages/nimble-blazor/NimbleBlazor/Components/NimbleDialog.razor.cs @@ -6,7 +6,7 @@ namespace NimbleBlazor; public partial class NimbleDialog : ComponentBase { private ElementReference _dialogElement; - private TCloseReason? _closeValue = default; + private TCloseReason? _closeValue; internal static string ShowDialogMethodName = "NimbleBlazor.Dialog.show"; internal static string CloseDialogMethodName = "NimbleBlazor.Dialog.close"; @@ -55,7 +55,7 @@ public partial class NimbleDialog : ComponentBase public async ValueTask> ShowAsync() { // Pass cancellation token to disable default async timeout - CancellationTokenSource source = new CancellationTokenSource(); + CancellationTokenSource source = new(); CancellationToken token = source.Token; var userDismissed = await JSRuntime!.InvokeAsync(ShowDialogMethodName, token, _dialogElement); var value = _closeValue; diff --git a/packages/nimble-blazor/NimbleBlazor/Components/NimbleDrawer.razor.cs b/packages/nimble-blazor/NimbleBlazor/Components/NimbleDrawer.razor.cs index 31037f27a7..4806010dd9 100644 --- a/packages/nimble-blazor/NimbleBlazor/Components/NimbleDrawer.razor.cs +++ b/packages/nimble-blazor/NimbleBlazor/Components/NimbleDrawer.razor.cs @@ -6,7 +6,7 @@ namespace NimbleBlazor; public partial class NimbleDrawer : ComponentBase { private ElementReference _drawerElement; - private TCloseReason? _closeValue = default; + private TCloseReason? _closeValue; internal static string ShowDrawerMethodName = "NimbleBlazor.Drawer.show"; internal static string CloseDrawerMethodName = "NimbleBlazor.Drawer.close"; @@ -32,7 +32,7 @@ public partial class NimbleDrawer : ComponentBase public async ValueTask> ShowAsync() { // Pass cancellation token to disable default async timeout - CancellationTokenSource source = new CancellationTokenSource(); + CancellationTokenSource source = new(); CancellationToken token = source.Token; var userDismissed = await JSRuntime!.InvokeAsync(ShowDrawerMethodName, token, _drawerElement); var value = _closeValue; diff --git a/packages/nimble-blazor/NimbleBlazor/Components/NimbleRadio.razor.cs b/packages/nimble-blazor/NimbleBlazor/Components/NimbleRadio.razor.cs index 0ad12191e3..c141ecb1c3 100644 --- a/packages/nimble-blazor/NimbleBlazor/Components/NimbleRadio.razor.cs +++ b/packages/nimble-blazor/NimbleBlazor/Components/NimbleRadio.razor.cs @@ -1,5 +1,4 @@ -using System.Diagnostics.CodeAnalysis; -using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components; namespace NimbleBlazor; diff --git a/packages/nimble-blazor/NimbleBlazor/Components/NimbleTable.razor.cs b/packages/nimble-blazor/NimbleBlazor/Components/NimbleTable.razor.cs index 1a21f1e3cc..8372894964 100644 --- a/packages/nimble-blazor/NimbleBlazor/Components/NimbleTable.razor.cs +++ b/packages/nimble-blazor/NimbleBlazor/Components/NimbleTable.razor.cs @@ -1,6 +1,5 @@ using System.Text.Json; using Microsoft.AspNetCore.Components; -using Microsoft.Extensions.Options; using Microsoft.JSInterop; namespace NimbleBlazor; @@ -14,6 +13,7 @@ namespace NimbleBlazor; public partial class NimbleTable : ComponentBase { private ElementReference _table; + private static readonly JsonSerializerOptions _serializationOptions = new() { MaxDepth = 3 }; internal static string SetTableDataMethodName = "NimbleBlazor.Table.setData"; internal static string GetSelectedRecordIdsMethodName = "NimbleBlazor.Table.getSelectedRecordIds"; internal static string SetSelectedRecordIdsMethodName = "NimbleBlazor.Table.setSelectedRecordIds"; @@ -45,8 +45,7 @@ public partial class NimbleTable : ComponentBase /// The data to set in the table public async Task SetDataAsync(IEnumerable data) { - var options = new JsonSerializerOptions { MaxDepth = 3 }; - await JSRuntime!.InvokeVoidAsync(SetTableDataMethodName, _table, JsonSerializer.Serialize(data, options)); + await JSRuntime!.InvokeVoidAsync(SetTableDataMethodName, _table, JsonSerializer.Serialize(data, _serializationOptions)); } /// diff --git a/packages/nimble-blazor/NimbleBlazor/Components/NimbleWaferMap.razor.cs b/packages/nimble-blazor/NimbleBlazor/Components/NimbleWaferMap.razor.cs index 85e16b37bf..cfba16adf9 100644 --- a/packages/nimble-blazor/NimbleBlazor/Components/NimbleWaferMap.razor.cs +++ b/packages/nimble-blazor/NimbleBlazor/Components/NimbleWaferMap.razor.cs @@ -10,12 +10,12 @@ namespace NimbleBlazor; public partial class NimbleWaferMap : ComponentBase { private ElementReference _waferMap; - private bool _diesUpdated = false; - private IEnumerable? _dies = Enumerable.Empty(); - private bool _colorScaleUpdated = false; + private bool _diesUpdated; + private IEnumerable? _dies; + private bool _colorScaleUpdated; private WaferMapColorScale? _colorScale; - private bool _highlightedTagsUpdated = false; - private IEnumerable? _highlightedTags = Enumerable.Empty(); + private bool _highlightedTagsUpdated; + private IEnumerable? _highlightedTags; internal static string GetWaferMapValidityMethodName = "NimbleBlazor.WaferMap.getValidity"; internal static string SetWaferMapDiesMethodName = "NimbleBlazor.WaferMap.setDies"; internal static string SetWaferMapColorScaleMethodName = "NimbleBlazor.WaferMap.setColorScale"; @@ -31,25 +31,25 @@ public partial class NimbleWaferMap : ComponentBase public WaferMapOriginLocation? OriginLocation { get; set; } /// - /// Represents the X coordinate of the minimum corner of the the grid bounding box for rendering the wafer map. + /// Represents the X coordinate of the minimum corner of the grid bounding box for rendering the wafer map. /// [Parameter] public double? GridMinX { get; set; } /// - /// Represents the X coordinate of the maximum corner of the the grid bounding box for rendering the wafer map. + /// Represents the X coordinate of the maximum corner of the grid bounding box for rendering the wafer map. /// [Parameter] public double? GridMaxX { get; set; } /// - /// Represents the Y coordinate of the minimum corner of the the grid bounding box for rendering the wafer map. + /// Represents the Y coordinate of the minimum corner of the grid bounding box for rendering the wafer map. /// [Parameter] public double? GridMinY { get; set; } /// - /// Represents the Y coordinate of the maximum corner of the the grid bounding box for rendering the wafer map. + /// Represents the Y coordinate of the maximum corner of the grid bounding box for rendering the wafer map. /// [Parameter] public double? GridMaxY { get; set; } diff --git a/packages/nimble-blazor/NimbleBlazor/DateTextColumnTypes.cs b/packages/nimble-blazor/NimbleBlazor/DateTextColumnTypes.cs index 39e89fa35c..b4a118199c 100644 --- a/packages/nimble-blazor/NimbleBlazor/DateTextColumnTypes.cs +++ b/packages/nimble-blazor/NimbleBlazor/DateTextColumnTypes.cs @@ -23,7 +23,7 @@ public enum LocaleMatcherAlgorithm internal static class LocaleMatcherAlgorithmExtensions { - private static readonly Dictionary _enumValues = new Dictionary + private static readonly Dictionary _enumValues = new() { [LocaleMatcherAlgorithm.BestFit] = "best fit", [LocaleMatcherAlgorithm.Lookup] = "lookup" @@ -68,7 +68,7 @@ public enum YearFormat internal static class YearFormatExtensions { - private static readonly Dictionary _enumValues = new Dictionary + private static readonly Dictionary _enumValues = new() { [YearFormat.Numeric] = "numeric", [YearFormat.TwoDigit] = "2-digit" @@ -88,7 +88,7 @@ public enum MonthFormat internal static class MonthFormatExtensions { - private static readonly Dictionary _enumValues = new Dictionary + private static readonly Dictionary _enumValues = new() { [MonthFormat.Numeric] = "numeric", [MonthFormat.TwoDigit] = "2-digit", @@ -108,7 +108,7 @@ public enum DayFormat internal static class DayFormatExtensions { - private static readonly Dictionary _enumValues = new Dictionary + private static readonly Dictionary _enumValues = new() { [DayFormat.Numeric] = "numeric", [DayFormat.TwoDigit] = "2-digit" @@ -125,7 +125,7 @@ public enum HourFormat internal static class HourFormatExtensions { - private static readonly Dictionary _enumValues = new Dictionary + private static readonly Dictionary _enumValues = new() { [HourFormat.Numeric] = "numeric", [HourFormat.TwoDigit] = "2-digit" @@ -142,7 +142,7 @@ public enum MinuteFormat internal static class MinuteFormatExtensions { - private static readonly Dictionary _enumValues = new Dictionary + private static readonly Dictionary _enumValues = new() { [MinuteFormat.Numeric] = "numeric", [MinuteFormat.TwoDigit] = "2-digit" @@ -159,7 +159,7 @@ public enum SecondFormat internal static class SecondFormatExtensions { - private static readonly Dictionary _enumValues = new Dictionary + private static readonly Dictionary _enumValues = new() { [SecondFormat.Numeric] = "numeric", [SecondFormat.TwoDigit] = "2-digit" @@ -180,7 +180,7 @@ public enum TimeZoneNameFormat internal static class TimeZoneNameFormatExtensions { - private static readonly Dictionary _enumValues = new Dictionary + private static readonly Dictionary _enumValues = new() { [TimeZoneNameFormat.Long] = "long", [TimeZoneNameFormat.Short] = "short", @@ -201,7 +201,7 @@ public enum FormatMatcherAlgorithm internal static class FormatMatcherAlgorithmExtensions { - private static readonly Dictionary _enumValues = new Dictionary + private static readonly Dictionary _enumValues = new() { [FormatMatcherAlgorithm.BestFit] = "best fit", [FormatMatcherAlgorithm.Basic] = "basic" @@ -264,7 +264,7 @@ public enum HourCycleFormat internal static class HourCycleFormatExtensions { - private static readonly Dictionary _enumValues = new Dictionary + private static readonly Dictionary _enumValues = new() { [HourCycleFormat.H11] = "h11", [HourCycleFormat.H12] = "h12", diff --git a/packages/nimble-blazor/NimbleBlazor/EventHandlers.cs b/packages/nimble-blazor/NimbleBlazor/EventHandlers.cs index 9f8818d93c..76bc33689f 100644 --- a/packages/nimble-blazor/NimbleBlazor/EventHandlers.cs +++ b/packages/nimble-blazor/NimbleBlazor/EventHandlers.cs @@ -1,5 +1,4 @@ -using System.Globalization; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; using Microsoft.AspNetCore.Components; namespace NimbleBlazor; diff --git a/packages/nimble-blazor/NimbleBlazor/NimbleBlazor.csproj b/packages/nimble-blazor/NimbleBlazor/NimbleBlazor.csproj index 447bd5be02..6da99a3012 100644 --- a/packages/nimble-blazor/NimbleBlazor/NimbleBlazor.csproj +++ b/packages/nimble-blazor/NimbleBlazor/NimbleBlazor.csproj @@ -36,7 +36,7 @@ - + diff --git a/packages/nimble-blazor/NimbleBlazor/NimbleInputBase.cs b/packages/nimble-blazor/NimbleBlazor/NimbleInputBase.cs index cb6637ba0c..236bb4c0b0 100644 --- a/packages/nimble-blazor/NimbleBlazor/NimbleInputBase.cs +++ b/packages/nimble-blazor/NimbleBlazor/NimbleInputBase.cs @@ -149,7 +149,7 @@ protected NimbleInputBase() /// True if the value could be parsed; otherwise false. protected virtual bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out TValue result, [NotNullWhen(false)] out string? validationErrorMessage) { - if (BindConverter.TryConvertTo(value, CultureInfo.InvariantCulture, out result)) + if (BindConverter.TryConvertTo(value, CultureInfo.InvariantCulture, out result)) { validationErrorMessage = null; return true; @@ -162,7 +162,7 @@ protected virtual bool TryParseValueFromString(string? value, [MaybeNullWhen(fal } /// - /// Gets a CSS class string that combines the class attribute and and a string indicating + /// Gets a CSS class string that combines the class attribute and a string indicating /// the status of the field being edited (a combination of "modified", "valid", and "invalid"). /// Derived components should typically use this value for the primary HTML element's 'class' attribute. /// diff --git a/packages/nimble-blazor/NimbleBlazor/NimbleMappingBase.cs b/packages/nimble-blazor/NimbleBlazor/NimbleMappingBase.cs index 6fa4475781..3f421a4ea3 100644 --- a/packages/nimble-blazor/NimbleBlazor/NimbleMappingBase.cs +++ b/packages/nimble-blazor/NimbleBlazor/NimbleMappingBase.cs @@ -10,7 +10,9 @@ public abstract class NimbleMappingBase : ComponentBase [Parameter] public TKey? Key { get; set; } +#pragma warning disable RCS1238 // Avoid nested ?: operators. public string? FormattedKey => (Key is bool b) ? (b ? "true" : "false") : Key?.ToString(); +#pragma warning restore RCS1238 // Avoid nested ?: operators. /// /// Gets or sets a collection of additional attributes that will be applied to the created element. diff --git a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/NimbleBlazor.Tests.Acceptance.csproj b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/NimbleBlazor.Tests.Acceptance.csproj index 08520ca39f..b3360d2f2b 100644 --- a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/NimbleBlazor.Tests.Acceptance.csproj +++ b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/NimbleBlazor.Tests.Acceptance.csproj @@ -25,7 +25,7 @@ - + diff --git a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/PlaywrightFixture.cs b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/PlaywrightFixture.cs index 25ff2dccef..f8706d87e8 100644 --- a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/PlaywrightFixture.cs +++ b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/PlaywrightFixture.cs @@ -1,6 +1,5 @@ using Microsoft.Playwright; using Xunit; -using PlaywrightProgram = Microsoft.Playwright.Program; namespace NimbleBlazor.Tests.Acceptance; diff --git a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Program.cs b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Program.cs index a4ce042610..bba031e698 100644 --- a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Program.cs +++ b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Program.cs @@ -1,21 +1,20 @@ -namespace NimbleBlazor.Tests.Acceptance +namespace NimbleBlazor.Tests.Acceptance; + +/// +/// Main entry point which spins up the web server and allows loading the Razor fixtures/pages in a browser +/// without running a specific test. +/// +public static class Program { - /// - /// Main entry point which spins up the web server and allows loading the Razor fixtures/pages in a browser - /// without running a specific test. - /// - public static class Program + public static void Main(string[] arguments) { - public static void Main(string[] arguments) - { - var builder = WebApplication.CreateBuilder(arguments); + var builder = WebApplication.CreateBuilder(arguments); - var startup = new Startup(builder.Configuration); - startup.ConfigureServices(builder.Services); - var app = builder.Build(); - startup.Configure(app); + var startup = new Startup(builder.Configuration); + startup.ConfigureServices(builder.Services); + var app = builder.Build(); + startup.Configure(app); - app.Run(); - } + app.Run(); } } diff --git a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Shared/MainLayout.razor.cs b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Shared/MainLayout.razor.cs index b51bec874f..df933abeb2 100644 --- a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Shared/MainLayout.razor.cs +++ b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Shared/MainLayout.razor.cs @@ -1,25 +1,23 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; using Microsoft.JSInterop; -using NimbleBlazor; -namespace NimbleBlazor.Tests.Acceptance.Shared +namespace NimbleBlazor.Tests.Acceptance.Shared; + +/// +/// The MainLayout Component. +/// +public partial class MainLayout { - /// - /// The MainLayout Component. - /// - public partial class MainLayout - { - private Theme Theme { get; set; } = Theme.Light; + private Theme Theme { get; set; } = Theme.Light; - public ErrorBoundary? ErrorBoundary { get; set; } + public ErrorBoundary? ErrorBoundary { get; set; } - [Inject] - public IJSRuntime? JSRuntime { get; set; } + [Inject] + public IJSRuntime? JSRuntime { get; set; } - protected override void OnParametersSet() - { - ErrorBoundary?.Recover(); - } + protected override void OnParametersSet() + { + ErrorBoundary?.Recover(); } } \ No newline at end of file diff --git a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/SharedPlaywrightCollectionDefinition.cs b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/SharedPlaywrightCollectionDefinition.cs index 9da0d17cf0..f3019290aa 100644 --- a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/SharedPlaywrightCollectionDefinition.cs +++ b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/SharedPlaywrightCollectionDefinition.cs @@ -1,12 +1,11 @@ using Xunit; -namespace NimbleBlazor.Tests.Acceptance +namespace NimbleBlazor.Tests.Acceptance; + +[CollectionDefinition(nameof(PlaywrightFixture))] +public class SharedPlaywrightCollectionDefinition : ICollectionFixture { - [CollectionDefinition(nameof(PlaywrightFixture))] - public class SharedPlaywrightCollectionDefinition : ICollectionFixture - { - // This class has no code, and is never created. Its purpose is simply - // to be the place to apply [CollectionDefinition] and all the - // ICollectionFixture<> interfaces. - } + // This class has no code, and is never created. Its purpose is simply + // to be the place to apply [CollectionDefinition] and all the + // ICollectionFixture<> interfaces. } diff --git a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/AcceptanceTestsBase.cs b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/AcceptanceTestsBase.cs index ea367980c1..528cabb19f 100644 --- a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/AcceptanceTestsBase.cs +++ b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/AcceptanceTestsBase.cs @@ -1,62 +1,61 @@ using Microsoft.Playwright; using Xunit; -namespace NimbleBlazor.Tests.Acceptance +namespace NimbleBlazor.Tests.Acceptance; + +[Collection(nameof(PlaywrightFixture))] +public abstract class AcceptanceTestsBase : IClassFixture { - [Collection(nameof(PlaywrightFixture))] - public abstract class AcceptanceTestsBase : IClassFixture + private readonly PlaywrightFixture _playwrightFixture; + private readonly BlazorServerWebHostFixture _blazorServerClassFixture; + + protected AcceptanceTestsBase( + PlaywrightFixture playwrightFixture, + BlazorServerWebHostFixture blazorServerClassFixture) { - private PlaywrightFixture _playwrightFixture; - private readonly BlazorServerWebHostFixture _blazorServerClassFixture; + _playwrightFixture = playwrightFixture; + _blazorServerClassFixture = blazorServerClassFixture; + } - protected AcceptanceTestsBase( - PlaywrightFixture playwrightFixture, - BlazorServerWebHostFixture blazorServerClassFixture) + private IBrowserContext BrowserContext + { + get { - _playwrightFixture = playwrightFixture; - _blazorServerClassFixture = blazorServerClassFixture; + return _playwrightFixture.BrowserContext!; } + } - private IBrowserContext BrowserContext - { - get - { - return _playwrightFixture.BrowserContext!; - } - } + protected async Task NewPageForRouteAsync(string route) + { + var page = await BrowserContext.NewPageAsync(); + await NavigateToPageAsync(page, route); + await WaitForNimbleBlazorInitializationAsync(page); + return new AsyncDisposablePage(page); + } - protected async Task NewPageForRouteAsync(string route) - { - var page = await BrowserContext.NewPageAsync(); - await NavigateToPageAsync(page, route); - await WaitForNimbleBlazorInitializationAsync(page); - return new AsyncDisposablePage(page); - } + private async Task NavigateToPageAsync(IPage page, string route) + { + var address = new Uri(_blazorServerClassFixture.ServerAddress!, route).AbsoluteUri; + await page.GotoAsync(address); + } - private async Task NavigateToPageAsync(IPage page, string route) - { - var address = new Uri(_blazorServerClassFixture.ServerAddress!, route).AbsoluteUri; - await page.GotoAsync(address); - } + private async Task WaitForNimbleBlazorInitializationAsync(IPage page) + { + await page.WaitForFunctionAsync("window.NimbleBlazor && window.NimbleBlazor.calledAfterStarted === true"); + } + + protected sealed class AsyncDisposablePage : IAsyncDisposable + { + public IPage Page { get; private set; } - private async Task WaitForNimbleBlazorInitializationAsync(IPage page) + public AsyncDisposablePage(IPage page) { - await page.WaitForFunctionAsync("window.NimbleBlazor && window.NimbleBlazor.calledAfterStarted === true"); + Page = page; } - protected sealed class AsyncDisposablePage : IAsyncDisposable + public async ValueTask DisposeAsync() { - public IPage Page { get; private set; } - - public AsyncDisposablePage(IPage page) - { - Page = page; - } - - public async ValueTask DisposeAsync() - { - await Page.CloseAsync(); - } + await Page.CloseAsync(); } } } diff --git a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/DialogTests.cs b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/DialogTests.cs index a904d818a5..0706576629 100644 --- a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/DialogTests.cs +++ b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/DialogTests.cs @@ -1,37 +1,36 @@ using Microsoft.Playwright; using Xunit; -namespace NimbleBlazor.Tests.Acceptance +namespace NimbleBlazor.Tests.Acceptance; + +public class DialogTests : AcceptanceTestsBase { - public class DialogTests : AcceptanceTestsBase + public DialogTests(PlaywrightFixture playwrightFixture, BlazorServerWebHostFixture blazorServerClassFixture) + : base(playwrightFixture, blazorServerClassFixture) { - public DialogTests(PlaywrightFixture playwrightFixture, BlazorServerWebHostFixture blazorServerClassFixture) - : base(playwrightFixture, blazorServerClassFixture) - { - } + } - [Fact] - public async Task Dialog_CanOpenAndCloseAsync() + [Fact] + public async Task Dialog_CanOpenAndCloseAsync() + { + await using (var pageWrapper = await NewPageForRouteAsync("DialogOpenAndClose")) { - await using (var pageWrapper = await NewPageForRouteAsync("DialogOpenAndClose")) - { - var page = pageWrapper.Page; - var openButton = page.Locator("nimble-button", new PageLocatorOptions() { HasText = "Open" }); - await openButton.ClickAsync(); + var page = pageWrapper.Page; + var openButton = page.Locator("nimble-button", new PageLocatorOptions() { HasText = "Open" }); + await openButton.ClickAsync(); - var dialog = page.Locator("nimble-dialog"); - var innerDialog = dialog.GetByRole(AriaRole.Dialog); - await Assertions.Expect(innerDialog).ToBeVisibleAsync(); - await Assertions.Expect(dialog).ToContainTextAsync("Example Dialog"); + var dialog = page.Locator("nimble-dialog"); + var innerDialog = dialog.GetByRole(AriaRole.Dialog); + await Assertions.Expect(innerDialog).ToBeVisibleAsync(); + await Assertions.Expect(dialog).ToContainTextAsync("Example Dialog"); - var closeButton = page.Locator("nimble-button", new PageLocatorOptions() { HasText = "Close" }); - await closeButton.ClickAsync(); + var closeButton = page.Locator("nimble-button", new PageLocatorOptions() { HasText = "Close" }); + await closeButton.ClickAsync(); - await Assertions.Expect(innerDialog).Not.ToBeVisibleAsync(); + await Assertions.Expect(innerDialog).Not.ToBeVisibleAsync(); - var textField = page.Locator("nimble-text-field"); - await Assertions.Expect(textField).ToHaveAttributeAsync("current-value", "Custom Close Reason"); - } + var textField = page.Locator("nimble-text-field"); + await Assertions.Expect(textField).ToHaveAttributeAsync("current-value", "Custom Close Reason"); } } } diff --git a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/DrawerTests.cs b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/DrawerTests.cs index b6598b1c7e..464c2f3f14 100644 --- a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/DrawerTests.cs +++ b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/DrawerTests.cs @@ -1,37 +1,36 @@ using Microsoft.Playwright; using Xunit; -namespace NimbleBlazor.Tests.Acceptance +namespace NimbleBlazor.Tests.Acceptance; + +public class DrawerTests : AcceptanceTestsBase { - public class DrawerTests : AcceptanceTestsBase + public DrawerTests(PlaywrightFixture playwrightFixture, BlazorServerWebHostFixture blazorServerClassFixture) + : base(playwrightFixture, blazorServerClassFixture) { - public DrawerTests(PlaywrightFixture playwrightFixture, BlazorServerWebHostFixture blazorServerClassFixture) - : base(playwrightFixture, blazorServerClassFixture) - { - } + } - [Fact] - public async Task Drawer_CanOpenAndCloseAsync() + [Fact] + public async Task Drawer_CanOpenAndCloseAsync() + { + await using (var pageWrapper = await NewPageForRouteAsync("DrawerOpenAndClose")) { - await using (var pageWrapper = await NewPageForRouteAsync("DrawerOpenAndClose")) - { - var page = pageWrapper.Page; - var openButton = page.Locator("nimble-button", new PageLocatorOptions() { HasText = "Open" }); - await openButton.ClickAsync(); + var page = pageWrapper.Page; + var openButton = page.Locator("nimble-button", new PageLocatorOptions() { HasText = "Open" }); + await openButton.ClickAsync(); - var drawer = page.Locator("nimble-drawer"); - var drawerInnerDialog = drawer.GetByRole(AriaRole.Dialog); - await Assertions.Expect(drawerInnerDialog).ToBeVisibleAsync(); - await Assertions.Expect(drawer).ToContainTextAsync("Example Drawer"); + var drawer = page.Locator("nimble-drawer"); + var drawerInnerDialog = drawer.GetByRole(AriaRole.Dialog); + await Assertions.Expect(drawerInnerDialog).ToBeVisibleAsync(); + await Assertions.Expect(drawer).ToContainTextAsync("Example Drawer"); - var closeButton = page.Locator("nimble-button", new PageLocatorOptions() { HasText = "Close" }); - await closeButton.ClickAsync(); + var closeButton = page.Locator("nimble-button", new PageLocatorOptions() { HasText = "Close" }); + await closeButton.ClickAsync(); - await Assertions.Expect(drawerInnerDialog).Not.ToBeVisibleAsync(); + await Assertions.Expect(drawerInnerDialog).Not.ToBeVisibleAsync(); - var textField = page.Locator("nimble-text-field"); - await Assertions.Expect(textField).ToHaveAttributeAsync("current-value", "Custom Close Reason"); - } + var textField = page.Locator("nimble-text-field"); + await Assertions.Expect(textField).ToHaveAttributeAsync("current-value", "Custom Close Reason"); } } } diff --git a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/TableColumnEnumTextTests.cs b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/TableColumnEnumTextTests.cs index 6d6b133902..666c4b937d 100644 --- a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/TableColumnEnumTextTests.cs +++ b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/TableColumnEnumTextTests.cs @@ -1,28 +1,27 @@ using Microsoft.Playwright; using Xunit; -namespace NimbleBlazor.Tests.Acceptance +namespace NimbleBlazor.Tests.Acceptance; + +public class TableColumnEnumTextTests : AcceptanceTestsBase { - public class TableColumnEnumTextTests : AcceptanceTestsBase + public TableColumnEnumTextTests(PlaywrightFixture playwrightFixture, BlazorServerWebHostFixture blazorServerClassFixture) + : base(playwrightFixture, blazorServerClassFixture) { - public TableColumnEnumTextTests(PlaywrightFixture playwrightFixture, BlazorServerWebHostFixture blazorServerClassFixture) - : base(playwrightFixture, blazorServerClassFixture) - { - } + } - [Fact] - public async Task TableColumnEnumText_IntKeyAsync() + [Fact] + public async Task TableColumnEnumText_IntKeyAsync() + { + await using (var pageWrapper = await NewPageForRouteAsync("TableColumnEnumTextIntKey")) { - await using (var pageWrapper = await NewPageForRouteAsync("TableColumnEnumTextIntKey")) - { - var page = pageWrapper.Page; - var table = page.Locator("nimble-table"); - await Assertions.Expect(table).ToBeVisibleAsync(); + var page = pageWrapper.Page; + var table = page.Locator("nimble-table"); + await Assertions.Expect(table).ToBeVisibleAsync(); - var rows = table.Locator("nimble-table-row"); - await Assertions.Expect(rows).ToHaveCountAsync(4); - await Assertions.Expect(rows).ToContainTextAsync(new string[] { "foo", "bar", "baz", string.Empty }); - } + var rows = table.Locator("nimble-table-row"); + await Assertions.Expect(rows).ToHaveCountAsync(4); + await Assertions.Expect(rows).ToContainTextAsync(new string[] { "foo", "bar", "baz", string.Empty }); } } } diff --git a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/TableColumnIconTests.cs b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/TableColumnIconTests.cs index cf62147334..b917ae3e81 100644 --- a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/TableColumnIconTests.cs +++ b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/TableColumnIconTests.cs @@ -1,30 +1,29 @@ using Microsoft.Playwright; using Xunit; -namespace NimbleBlazor.Tests.Acceptance +namespace NimbleBlazor.Tests.Acceptance; + +public class TableColumnIconTests : AcceptanceTestsBase { - public class TableColumnIconTests : AcceptanceTestsBase + public TableColumnIconTests(PlaywrightFixture playwrightFixture, BlazorServerWebHostFixture blazorServerClassFixture) + : base(playwrightFixture, blazorServerClassFixture) { - public TableColumnIconTests(PlaywrightFixture playwrightFixture, BlazorServerWebHostFixture blazorServerClassFixture) - : base(playwrightFixture, blazorServerClassFixture) - { - } + } - [Fact] - public async Task TableColumnIcon_BoolKeyAsync() + [Fact] + public async Task TableColumnIcon_BoolKeyAsync() + { + await using (var pageWrapper = await NewPageForRouteAsync("TableColumnIconBoolKey")) { - await using (var pageWrapper = await NewPageForRouteAsync("TableColumnIconBoolKey")) - { - var page = pageWrapper.Page; - var table = page.Locator("nimble-table"); - await Assertions.Expect(table).ToBeVisibleAsync(); + var page = pageWrapper.Page; + var table = page.Locator("nimble-table"); + await Assertions.Expect(table).ToBeVisibleAsync(); - var icon = table.Locator("nimble-icon-check"); - await Assertions.Expect(icon).ToHaveCountAsync(1); - await Assertions.Expect(icon).ToHaveAttributeAsync("severity", "success"); - var spinner = table.Locator("nimble-spinner"); - await Assertions.Expect(spinner).ToHaveCountAsync(1); - } + var icon = table.Locator("nimble-icon-check"); + await Assertions.Expect(icon).ToHaveCountAsync(1); + await Assertions.Expect(icon).ToHaveAttributeAsync("severity", "success"); + var spinner = table.Locator("nimble-spinner"); + await Assertions.Expect(spinner).ToHaveCountAsync(1); } } } diff --git a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/TableColumnNumberTextTests.cs b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/TableColumnNumberTextTests.cs index 0e2191334b..dcab13fd97 100644 --- a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/TableColumnNumberTextTests.cs +++ b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/TableColumnNumberTextTests.cs @@ -1,28 +1,27 @@ using Microsoft.Playwright; using Xunit; -namespace NimbleBlazor.Tests.Acceptance +namespace NimbleBlazor.Tests.Acceptance; + +public class TableColumnNumberTextTests : AcceptanceTestsBase { - public class TableColumnNumberTextTests : AcceptanceTestsBase + public TableColumnNumberTextTests(PlaywrightFixture playwrightFixture, BlazorServerWebHostFixture blazorServerClassFixture) + : base(playwrightFixture, blazorServerClassFixture) { - public TableColumnNumberTextTests(PlaywrightFixture playwrightFixture, BlazorServerWebHostFixture blazorServerClassFixture) - : base(playwrightFixture, blazorServerClassFixture) - { - } + } - [Fact] - public async Task TableColumnNumberText_BytesUnitAsync() + [Fact] + public async Task TableColumnNumberText_BytesUnitAsync() + { + await using (var pageWrapper = await NewPageForRouteAsync("TableColumnNumberText")) { - await using (var pageWrapper = await NewPageForRouteAsync("TableColumnNumberText")) - { - var page = pageWrapper.Page; - var table = page.Locator("nimble-table"); - await Assertions.Expect(table).ToBeVisibleAsync(); + var page = pageWrapper.Page; + var table = page.Locator("nimble-table"); + await Assertions.Expect(table).ToBeVisibleAsync(); - var unitByte = table.Locator("nimble-unit-byte"); - await Assertions.Expect(unitByte).ToHaveCountAsync(1); - await Assertions.Expect(unitByte).ToHaveAttributeAsync("binary", string.Empty); - } + var unitByte = table.Locator("nimble-unit-byte"); + await Assertions.Expect(unitByte).ToHaveCountAsync(1); + await Assertions.Expect(unitByte).ToHaveAttributeAsync("binary", string.Empty); } } } diff --git a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/TableTests.cs b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/TableTests.cs index 2ef27ad634..c2279f79f5 100644 --- a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/TableTests.cs +++ b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/TableTests.cs @@ -1,90 +1,90 @@ using Microsoft.Playwright; using Xunit; -namespace NimbleBlazor.Tests.Acceptance +namespace NimbleBlazor.Tests.Acceptance; + +public class TableTests : AcceptanceTestsBase { - public class TableTests : AcceptanceTestsBase + public TableTests(PlaywrightFixture playwrightFixture, BlazorServerWebHostFixture blazorServerClassFixture) + : base(playwrightFixture, blazorServerClassFixture) { - public TableTests(PlaywrightFixture playwrightFixture, BlazorServerWebHostFixture blazorServerClassFixture) - : base(playwrightFixture, blazorServerClassFixture) - { - } + } - [Fact] - public async Task Table_RendersBoundDataAsync() + [Fact] + public async Task Table_RendersBoundDataAsync() + { + await using (var pageWrapper = await NewPageForRouteAsync("TableSetData")) { - await using (var pageWrapper = await NewPageForRouteAsync("TableSetData")) - { - var page = pageWrapper.Page; - var table = page.Locator("nimble-table"); - await Assertions.Expect(table).ToBeVisibleAsync(); + var page = pageWrapper.Page; + var table = page.Locator("nimble-table"); + await Assertions.Expect(table).ToBeVisibleAsync(); - var rows = table.Locator("nimble-table-row"); - await Assertions.Expect(rows).ToHaveCountAsync(5); - await Assertions.Expect(rows).ToContainTextAsync(new string[] { "A0", "A1", "A2", "A3", "A4" }); - } + var rows = table.Locator("nimble-table-row"); + await Assertions.Expect(rows).ToHaveCountAsync(5); + var expected = new string[] { "A0", "A1", "A2", "A3", "A4" }; + await Assertions.Expect(rows).ToContainTextAsync(expected); } + } - [Theory] - [InlineData(0, TableRecordDelayedHierarchyState.CanLoadChildren)] - [InlineData(1, TableRecordDelayedHierarchyState.None)] - [InlineData(2, TableRecordDelayedHierarchyState.LoadingChildren)] - [InlineData(3, TableRecordDelayedHierarchyState.None)] - public async Task Table_RendersHierarchyOptionsAsync(int rowIndex, TableRecordDelayedHierarchyState expectedHierarchyState) + [Theory] + [InlineData(0, TableRecordDelayedHierarchyState.CanLoadChildren)] + [InlineData(1, TableRecordDelayedHierarchyState.None)] + [InlineData(2, TableRecordDelayedHierarchyState.LoadingChildren)] + [InlineData(3, TableRecordDelayedHierarchyState.None)] + public async Task Table_RendersHierarchyOptionsAsync(int rowIndex, TableRecordDelayedHierarchyState expectedHierarchyState) + { + await using (var pageWrapper = await NewPageForRouteAsync("TableSetRecordHierarchyOptionsTest")) { - await using (var pageWrapper = await NewPageForRouteAsync("TableSetRecordHierarchyOptionsTest")) - { - var page = pageWrapper.Page; - var table = page.Locator("nimble-table"); - await Assertions.Expect(table).ToBeVisibleAsync(); + var page = pageWrapper.Page; + var table = page.Locator("nimble-table"); + await Assertions.Expect(table).ToBeVisibleAsync(); - var rows = table.Locator("nimble-table-row"); - await Assertions.Expect(rows).ToHaveCountAsync(4); + var rows = table.Locator("nimble-table-row"); + await Assertions.Expect(rows).ToHaveCountAsync(4); - var row = rows.Nth(rowIndex); - var rowExpandCollapseButton = row.Locator("nimble-button"); - var rowSpinner = row.Locator("nimble-spinner"); + var row = rows.Nth(rowIndex); + var rowExpandCollapseButton = row.Locator("nimble-button"); + var rowSpinner = row.Locator("nimble-spinner"); - if (expectedHierarchyState == TableRecordDelayedHierarchyState.CanLoadChildren) - { - await Assertions.Expect(rowExpandCollapseButton).ToBeVisibleAsync(); - } - else - { - await Assertions.Expect(rowExpandCollapseButton).Not.ToBeVisibleAsync(); - } + if (expectedHierarchyState == TableRecordDelayedHierarchyState.CanLoadChildren) + { + await Assertions.Expect(rowExpandCollapseButton).ToBeVisibleAsync(); + } + else + { + await Assertions.Expect(rowExpandCollapseButton).Not.ToBeVisibleAsync(); + } - if (expectedHierarchyState == TableRecordDelayedHierarchyState.LoadingChildren) - { - await Assertions.Expect(rowSpinner).ToBeVisibleAsync(); - } - else - { - await Assertions.Expect(rowSpinner).Not.ToBeVisibleAsync(); - } + if (expectedHierarchyState == TableRecordDelayedHierarchyState.LoadingChildren) + { + await Assertions.Expect(rowSpinner).ToBeVisibleAsync(); + } + else + { + await Assertions.Expect(rowSpinner).Not.ToBeVisibleAsync(); } } + } - [Fact] - public async Task Table_TriggersRowExpandToggleEventAsync() + [Fact] + public async Task Table_TriggersRowExpandToggleEventAsync() + { + await using (var pageWrapper = await NewPageForRouteAsync("TableSetRecordHierarchyOptionsTest")) { - await using (var pageWrapper = await NewPageForRouteAsync("TableSetRecordHierarchyOptionsTest")) - { - var page = pageWrapper.Page; - var table = page.Locator("nimble-table"); - await Assertions.Expect(table).ToBeVisibleAsync(); - var textField = page.Locator("nimble-text-field"); + var page = pageWrapper.Page; + var table = page.Locator("nimble-table"); + await Assertions.Expect(table).ToBeVisibleAsync(); + var textField = page.Locator("nimble-text-field"); - var rows = table.Locator("nimble-table-row"); - var expandableRow = rows.Nth(0); - var rowExpandCollapseButton = expandableRow.Locator("nimble-button"); + var rows = table.Locator("nimble-table-row"); + var expandableRow = rows.Nth(0); + var rowExpandCollapseButton = expandableRow.Locator("nimble-button"); - await rowExpandCollapseButton.ClickAsync(); - await Assertions.Expect(textField).ToHaveAttributeAsync("current-value", "RecordId: 0, OldState: False, NewState: True"); + await rowExpandCollapseButton.ClickAsync(); + await Assertions.Expect(textField).ToHaveAttributeAsync("current-value", "RecordId: 0, OldState: False, NewState: True"); - await rowExpandCollapseButton.ClickAsync(); - await Assertions.Expect(textField).ToHaveAttributeAsync("current-value", "RecordId: 0, OldState: True, NewState: False"); - } + await rowExpandCollapseButton.ClickAsync(); + await Assertions.Expect(textField).ToHaveAttributeAsync("current-value", "RecordId: 0, OldState: True, NewState: False"); } } } diff --git a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/ThemeProviderTests.cs b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/ThemeProviderTests.cs index 76f2afba63..9d5055c982 100644 --- a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/ThemeProviderTests.cs +++ b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/ThemeProviderTests.cs @@ -1,34 +1,33 @@ using Microsoft.Playwright; using Xunit; -namespace NimbleBlazor.Tests.Acceptance +namespace NimbleBlazor.Tests.Acceptance; + +public class ThemeProviderTests : AcceptanceTestsBase { - public class ThemeProviderTests : AcceptanceTestsBase + public ThemeProviderTests(PlaywrightFixture playwrightFixture, BlazorServerWebHostFixture blazorServerClassFixture) + : base(playwrightFixture, blazorServerClassFixture) { - public ThemeProviderTests(PlaywrightFixture playwrightFixture, BlazorServerWebHostFixture blazorServerClassFixture) - : base(playwrightFixture, blazorServerClassFixture) - { - } + } - [Fact] - public async Task ThemeProvider_ValidityAndCheckValidityWorkAsync() + [Fact] + public async Task ThemeProvider_ValidityAndCheckValidityWorkAsync() + { + await using (var pageWrapper = await NewPageForRouteAsync("ThemeProvider")) { - await using (var pageWrapper = await NewPageForRouteAsync("ThemeProvider")) - { - var page = pageWrapper.Page; - var validButton = page.Locator("nimble-button", new PageLocatorOptions() { HasText = "Set Valid Lang" }); - var invalidButton = page.Locator("nimble-button", new PageLocatorOptions() { HasText = "Set Invalid Lang" }); - var isValidCheckbox = page.Locator("nimble-checkbox", new PageLocatorOptions() { HasText = "IsValid" }); - var langIsInvalidCheckbox = page.Locator("nimble-checkbox", new PageLocatorOptions() { HasText = "InvalidLang" }); + var page = pageWrapper.Page; + var validButton = page.Locator("nimble-button", new PageLocatorOptions() { HasText = "Set Valid Lang" }); + var invalidButton = page.Locator("nimble-button", new PageLocatorOptions() { HasText = "Set Invalid Lang" }); + var isValidCheckbox = page.Locator("nimble-checkbox", new PageLocatorOptions() { HasText = "IsValid" }); + var langIsInvalidCheckbox = page.Locator("nimble-checkbox", new PageLocatorOptions() { HasText = "InvalidLang" }); - await invalidButton.ClickAsync(); - await Assertions.Expect(isValidCheckbox).Not.ToBeCheckedAsync(); - await Assertions.Expect(langIsInvalidCheckbox).ToBeCheckedAsync(); + await invalidButton.ClickAsync(); + await Assertions.Expect(isValidCheckbox).Not.ToBeCheckedAsync(); + await Assertions.Expect(langIsInvalidCheckbox).ToBeCheckedAsync(); - await validButton.ClickAsync(); - await Assertions.Expect(isValidCheckbox).ToBeCheckedAsync(); - await Assertions.Expect(langIsInvalidCheckbox).Not.ToBeCheckedAsync(); - } + await validButton.ClickAsync(); + await Assertions.Expect(isValidCheckbox).ToBeCheckedAsync(); + await Assertions.Expect(langIsInvalidCheckbox).Not.ToBeCheckedAsync(); } } } diff --git a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/WaferMapTests.cs b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/WaferMapTests.cs index ed8f68aa22..3a2f5d1890 100644 --- a/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/WaferMapTests.cs +++ b/packages/nimble-blazor/Tests/NimbleBlazor.Tests.Acceptance/Tests/WaferMapTests.cs @@ -1,59 +1,58 @@ using Microsoft.Playwright; using Xunit; -namespace NimbleBlazor.Tests.Acceptance +namespace NimbleBlazor.Tests.Acceptance; + +public class WaferMapTests : AcceptanceTestsBase { - public class WaferMapTests : AcceptanceTestsBase + private const int RenderingTimeout = 200; + public WaferMapTests(PlaywrightFixture playwrightFixture, BlazorServerWebHostFixture blazorServerClassFixture) + : base(playwrightFixture, blazorServerClassFixture) + { } + + [Fact] + public async Task WaferMap_WithDiesAndColorScale_RendersColorsAsync() + { + await using var pageWrapper = await NewPageForRouteAsync("WaferMapRenderTest"); + var page = pageWrapper.Page; + var canvas = page.Locator("canvas"); + + await Assertions.Expect(canvas).ToBeVisibleAsync(); + await Task.Delay(RenderingTimeout); + var color = await page.EvaluateAsync( + @"document.getElementsByTagName('nimble-wafer-map')[0].canvas.getContext('2d').getImageData(249, 249, 1, 1).data.toString()"); + + Assert.Equal(@"85,85,0,255", color); + } + + [Fact] + public async Task WaferMap_WithGridDimensions_IsValidAsync() { - private const int RenderingTimeout = 200; - public WaferMapTests(PlaywrightFixture playwrightFixture, BlazorServerWebHostFixture blazorServerClassFixture) - : base(playwrightFixture, blazorServerClassFixture) - { } - - [Fact] - public async Task WaferMap_WithDiesAndColorScale_RendersColorsAsync() - { - await using var pageWrapper = await NewPageForRouteAsync("WaferMapRenderTest"); - var page = pageWrapper.Page; - var canvas = page.Locator("canvas"); - - await Assertions.Expect(canvas).ToBeVisibleAsync(); - await Task.Delay(RenderingTimeout); - var color = await page.EvaluateAsync( - @"document.getElementsByTagName('nimble-wafer-map')[0].canvas.getContext('2d').getImageData(249, 249, 1, 1).data.toString()"); - - Assert.Equal(@"85,85,0,255", color); - } - - [Fact] - public async Task WaferMap_WithGridDimensions_IsValidAsync() - { - await using var pageWrapper = await NewPageForRouteAsync("WaferMapRenderTest"); - var page = pageWrapper.Page; - var canvas = page.Locator("canvas"); - var validButton = page.Locator("nimble-button"); - var textField = page.Locator("nimble-text-field"); - - await Assertions.Expect(canvas).ToBeVisibleAsync(); - await Task.Delay(RenderingTimeout); - await validButton.ClickAsync(); - - await Assertions.Expect(textField).ToHaveAttributeAsync("current-value", "False"); - } - - [Fact] - public async Task WaferMap_WithHoverEvent_TriggersDieChangeEventAsync() - { - await using var pageWrapper = await NewPageForRouteAsync("WaferMapRenderTest"); - var page = pageWrapper.Page; - var canvas = page.Locator("canvas"); - var textField = page.Locator("nimble-text-field"); - - await Assertions.Expect(canvas).ToBeVisibleAsync(); - await Task.Delay(RenderingTimeout); - await canvas.HoverAsync(); - - await Assertions.Expect(textField).ToHaveAttributeAsync("current-value", "4"); - } + await using var pageWrapper = await NewPageForRouteAsync("WaferMapRenderTest"); + var page = pageWrapper.Page; + var canvas = page.Locator("canvas"); + var validButton = page.Locator("nimble-button"); + var textField = page.Locator("nimble-text-field"); + + await Assertions.Expect(canvas).ToBeVisibleAsync(); + await Task.Delay(RenderingTimeout); + await validButton.ClickAsync(); + + await Assertions.Expect(textField).ToHaveAttributeAsync("current-value", "False"); + } + + [Fact] + public async Task WaferMap_WithHoverEvent_TriggersDieChangeEventAsync() + { + await using var pageWrapper = await NewPageForRouteAsync("WaferMapRenderTest"); + var page = pageWrapper.Page; + var canvas = page.Locator("canvas"); + var textField = page.Locator("nimble-text-field"); + + await Assertions.Expect(canvas).ToBeVisibleAsync(); + await Task.Delay(RenderingTimeout); + await canvas.HoverAsync(); + + await Assertions.Expect(textField).ToHaveAttributeAsync("current-value", "4"); } } diff --git a/packages/nimble-blazor/Tests/NimbleBlazor.Tests/NimbleBlazor.Tests.csproj b/packages/nimble-blazor/Tests/NimbleBlazor.Tests/NimbleBlazor.Tests.csproj index 3f6da0db3b..a677b0df55 100644 --- a/packages/nimble-blazor/Tests/NimbleBlazor.Tests/NimbleBlazor.Tests.csproj +++ b/packages/nimble-blazor/Tests/NimbleBlazor.Tests/NimbleBlazor.Tests.csproj @@ -31,7 +31,7 @@ - + diff --git a/packages/nimble-blazor/Tests/NimbleBlazor.Tests/Unit/Components/NimbleAnchorButtonTests.cs b/packages/nimble-blazor/Tests/NimbleBlazor.Tests/Unit/Components/NimbleAnchorButtonTests.cs index 65a021286b..f4460907f9 100644 --- a/packages/nimble-blazor/Tests/NimbleBlazor.Tests/Unit/Components/NimbleAnchorButtonTests.cs +++ b/packages/nimble-blazor/Tests/NimbleBlazor.Tests/Unit/Components/NimbleAnchorButtonTests.cs @@ -1,7 +1,6 @@ using System; using System.Linq.Expressions; using Bunit; -using Microsoft.AspNetCore.Components; using Xunit; namespace NimbleBlazor.Tests.Unit.Components; diff --git a/packages/nimble-blazor/Tests/NimbleBlazor.Tests/Unit/Components/NimbleTableTests.cs b/packages/nimble-blazor/Tests/NimbleBlazor.Tests/Unit/Components/NimbleTableTests.cs index 661c1581fc..84fa10ec07 100644 --- a/packages/nimble-blazor/Tests/NimbleBlazor.Tests/Unit/Components/NimbleTableTests.cs +++ b/packages/nimble-blazor/Tests/NimbleBlazor.Tests/Unit/Components/NimbleTableTests.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq.Expressions; -using System.Security.Principal; using System.Text.Json; using System.Threading.Tasks; using Bunit; @@ -14,7 +13,7 @@ namespace NimbleBlazor.Tests.Unit.Components; /// public class NimbleTableTests { - internal class TableRowData + internal sealed class TableRowData { public TableRowData(string firstName, string lastName) { @@ -25,7 +24,7 @@ public TableRowData(string firstName, string lastName) public string LastName { get; set; } } - internal class BadTableRowData + internal sealed class BadTableRowData { public BadTableRowData(string firstName, string lastName, BadTableRowData? parent = null) { @@ -98,8 +97,10 @@ public void TextFieldAppearance_AttributeIsSet(TableRowSelectionMode value, stri [Fact] public void NimbleTable_WithClassAttribute_HasTableMarkup() { - IDictionary classAttribute = new Dictionary(); - classAttribute.Add("class", "table"); + IDictionary classAttribute = new Dictionary + { + { "class", "table" } + }; var table = RenderWithPropertySet, TableRowData>(x => x.AdditionalAttributes!, classAttribute); var expectedMarkup = @"class=""table"""; @@ -114,9 +115,8 @@ public async Task NimbleTable_GivenSupportedData_ThrowsNoExceptionAsync() var tableData = new TableRowData[] { parentRowData, childRowData }; var table = Render(); - var ex = Record.ExceptionAsync(async () => { await table.Instance.SetDataAsync(tableData); }); - - Assert.Null(ex.Result); + var exception = await Record.ExceptionAsync(async () => { await table.Instance.SetDataAsync(tableData); }); + Assert.Null(exception); } [Fact] @@ -127,9 +127,9 @@ public async Task NimbleTable_GivenUnsupportedData_ThrowsJsonExceptionAsync() var tableData = new BadTableRowData[] { parentRowData, childRowData }; var table = Render(); - var ex = Record.ExceptionAsync(async () => { await table.Instance.SetDataAsync(tableData); }); + var exception = await Record.ExceptionAsync(async () => { await table.Instance.SetDataAsync(tableData); }); - Assert.IsType(ex.Result); + Assert.IsType(exception); } private IRenderedComponent> RenderWithPropertySet(Expression, TProperty>> propertyGetter, TProperty propertyValue)