diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs index 2e284fb034f..3d10a8cacba 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests; @@ -217,4 +218,46 @@ public class MyComponent : ComponentBase "The start tag name 'MyComponent' does not match the end tag name 'mycomponent'. Components must have matching start and end tag names (case-sensitive).", diagnostic.GetMessage(CultureInfo.CurrentCulture)); } + + [Fact, WorkItem("https://github.com/dotnet/aspnetcore/issues/23228")] + public void AttributeBinding_ExtraClosingParenthesis_TreatedAsLiteralText() + { + // Arrange/Act + // This reproduces https://github.com/dotnet/aspnetcore/issues/23228 + // An extra closing parenthesis in an attribute binding is currently treated as literal text + // rather than producing a diagnostic error + var generated = CompileToCSharp(@" +@page ""/"" + +@foreach (var item in new[] { Architecture.Windows, Architecture.MacOSX, Architecture.Linux }) +{ + +} +

@current

+@code { + enum Architecture + { + None, + Windows, + MacOSX, + Linux + } + Architecture current = Architecture.None; + bool IsActive(Architecture arch) => current == arch; + void ChangeArchitecture(Architecture arch) => current = arch; +}"); + + // Assert + // The compiler currently treats the extra ')' as literal text and generates: + // __builder.AddAttribute(6, "checked", (IsActive(item)) + ")"); + // This is valid C# but produces incorrect Blazor behavior (UI out of sync) + // No diagnostic is currently reported for this issue + Assert.Empty(generated.RazorDiagnostics); + } }