diff --git a/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.AsyncBoolMethod.DotNet10_0.verified.txt b/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.AsyncBoolMethod.DotNet10_0.verified.txt index ed3acbadf3..01be921f77 100644 --- a/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.AsyncBoolMethod.DotNet10_0.verified.txt +++ b/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.AsyncBoolMethod.DotNet10_0.verified.txt @@ -34,7 +34,7 @@ public sealed class Int_IsPositiveAsync_Assertion : Assertion var result = await value!.IsPositiveAsync(); return result ? AssertionResult.Passed - : AssertionResult.Failed($"found {value}")); + : AssertionResult.Failed($"found {value}"); } protected override string GetExpectation() @@ -69,7 +69,7 @@ public sealed class Int_IsGreaterThanAsync_Int_Assertion : Assertion var result = await value!.IsGreaterThanAsync(_threshold); return result ? AssertionResult.Passed - : AssertionResult.Failed($"found {value}")); + : AssertionResult.Failed($"found {value}"); } protected override string GetExpectation() diff --git a/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.AsyncBoolMethod.DotNet8_0.verified.txt b/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.AsyncBoolMethod.DotNet8_0.verified.txt index ed3acbadf3..01be921f77 100644 --- a/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.AsyncBoolMethod.DotNet8_0.verified.txt +++ b/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.AsyncBoolMethod.DotNet8_0.verified.txt @@ -34,7 +34,7 @@ public sealed class Int_IsPositiveAsync_Assertion : Assertion var result = await value!.IsPositiveAsync(); return result ? AssertionResult.Passed - : AssertionResult.Failed($"found {value}")); + : AssertionResult.Failed($"found {value}"); } protected override string GetExpectation() @@ -69,7 +69,7 @@ public sealed class Int_IsGreaterThanAsync_Int_Assertion : Assertion var result = await value!.IsGreaterThanAsync(_threshold); return result ? AssertionResult.Passed - : AssertionResult.Failed($"found {value}")); + : AssertionResult.Failed($"found {value}"); } protected override string GetExpectation() diff --git a/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.AsyncBoolMethod.DotNet9_0.verified.txt b/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.AsyncBoolMethod.DotNet9_0.verified.txt index ed3acbadf3..01be921f77 100644 --- a/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.AsyncBoolMethod.DotNet9_0.verified.txt +++ b/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.AsyncBoolMethod.DotNet9_0.verified.txt @@ -34,7 +34,7 @@ public sealed class Int_IsPositiveAsync_Assertion : Assertion var result = await value!.IsPositiveAsync(); return result ? AssertionResult.Passed - : AssertionResult.Failed($"found {value}")); + : AssertionResult.Failed($"found {value}"); } protected override string GetExpectation() @@ -69,7 +69,7 @@ public sealed class Int_IsGreaterThanAsync_Int_Assertion : Assertion var result = await value!.IsGreaterThanAsync(_threshold); return result ? AssertionResult.Passed - : AssertionResult.Failed($"found {value}")); + : AssertionResult.Failed($"found {value}"); } protected override string GetExpectation() diff --git a/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.AsyncBoolMethod.Net4_7.verified.txt b/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.AsyncBoolMethod.Net4_7.verified.txt index ed3acbadf3..01be921f77 100644 --- a/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.AsyncBoolMethod.Net4_7.verified.txt +++ b/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.AsyncBoolMethod.Net4_7.verified.txt @@ -34,7 +34,7 @@ public sealed class Int_IsPositiveAsync_Assertion : Assertion var result = await value!.IsPositiveAsync(); return result ? AssertionResult.Passed - : AssertionResult.Failed($"found {value}")); + : AssertionResult.Failed($"found {value}"); } protected override string GetExpectation() @@ -69,7 +69,7 @@ public sealed class Int_IsGreaterThanAsync_Int_Assertion : Assertion var result = await value!.IsGreaterThanAsync(_threshold); return result ? AssertionResult.Passed - : AssertionResult.Failed($"found {value}")); + : AssertionResult.Failed($"found {value}"); } protected override string GetExpectation() diff --git a/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.cs b/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.cs index 7ba9a7dd73..43fc0d2c60 100644 --- a/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.cs +++ b/TUnit.Assertions.SourceGenerator.Tests/MethodAssertionGeneratorTests.cs @@ -53,6 +53,11 @@ public Task AsyncBoolMethod() => RunTest( await Assert.That(mainFile).IsNotNull(); await Assert.That(mainFile!).Contains("IsPositiveAsync_Assertion"); await Assert.That(mainFile!).Contains("var result = await"); // Awaits Task + // The Task branch's failure-return must terminate with a single `);` — + // a `));` (two closing parens) is a literal C# syntax error that pins this + // assertion against the regression where the emit had an extra closing paren. + await Assert.That(mainFile!).DoesNotContain("Failed($\"found {value}\"));"); + await Assert.That(mainFile!).Contains("Failed($\"found {value}\");"); }); [Test] diff --git a/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_GeneratesValidCSharp.DotNet10_0.verified.txt b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_GeneratesValidCSharp.DotNet10_0.verified.txt new file mode 100644 index 0000000000..01be921f77 --- /dev/null +++ b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_GeneratesValidCSharp.DotNet10_0.verified.txt @@ -0,0 +1,103 @@ +[ +// +#pragma warning disable +#nullable enable + +using System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using TUnit.Assertions.Core; +using TUnit.Assertions.Tests.TestData; + +namespace TUnit.Assertions.Extensions; + +/// +/// Generated assertion for IsPositiveAsync +/// +public sealed class Int_IsPositiveAsync_Assertion : Assertion +{ + public Int_IsPositiveAsync_Assertion(AssertionContext context) + : base(context) + { + } + + protected override async Task CheckAsync(EvaluationMetadata metadata) + { + var value = metadata.Value; + var exception = metadata.Exception; + + if (exception != null) + { + return AssertionResult.Failed($"threw {exception.GetType().FullName}"); + } + + var result = await value!.IsPositiveAsync(); + return result + ? AssertionResult.Passed + : AssertionResult.Failed($"found {value}"); + } + + protected override string GetExpectation() + { + return "to satisfy IsPositiveAsync"; + } +} + +/// +/// Generated assertion for IsGreaterThanAsync +/// +public sealed class Int_IsGreaterThanAsync_Int_Assertion : Assertion +{ + private readonly int _threshold; + + public Int_IsGreaterThanAsync_Int_Assertion(AssertionContext context, int threshold) + : base(context) + { + _threshold = threshold; + } + + protected override async Task CheckAsync(EvaluationMetadata metadata) + { + var value = metadata.Value; + var exception = metadata.Exception; + + if (exception != null) + { + return AssertionResult.Failed($"threw {exception.GetType().FullName}"); + } + + var result = await value!.IsGreaterThanAsync(_threshold); + return result + ? AssertionResult.Passed + : AssertionResult.Failed($"found {value}"); + } + + protected override string GetExpectation() + { + return $"to satisfy IsGreaterThanAsync({_threshold})"; + } +} + +public static partial class AsyncBoolAssertionExtensions +{ + /// + /// Generated extension method for IsPositiveAsync + /// + public static Int_IsPositiveAsync_Assertion IsPositiveAsync(this IAssertionSource source) + { + source.Context.ExpressionBuilder.Append(".IsPositiveAsync()"); + return new Int_IsPositiveAsync_Assertion(source.Context); + } + + /// + /// Generated extension method for IsGreaterThanAsync + /// + public static Int_IsGreaterThanAsync_Int_Assertion IsGreaterThanAsync(this IAssertionSource source, int threshold, [CallerArgumentExpression(nameof(threshold))] string? thresholdExpression = null) + { + source.Context.ExpressionBuilder.Append($".IsGreaterThanAsync({thresholdExpression})"); + return new Int_IsGreaterThanAsync_Int_Assertion(source.Context, threshold); + } + +} + +] \ No newline at end of file diff --git a/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_GeneratesValidCSharp.DotNet8_0.verified.txt b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_GeneratesValidCSharp.DotNet8_0.verified.txt new file mode 100644 index 0000000000..01be921f77 --- /dev/null +++ b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_GeneratesValidCSharp.DotNet8_0.verified.txt @@ -0,0 +1,103 @@ +[ +// +#pragma warning disable +#nullable enable + +using System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using TUnit.Assertions.Core; +using TUnit.Assertions.Tests.TestData; + +namespace TUnit.Assertions.Extensions; + +/// +/// Generated assertion for IsPositiveAsync +/// +public sealed class Int_IsPositiveAsync_Assertion : Assertion +{ + public Int_IsPositiveAsync_Assertion(AssertionContext context) + : base(context) + { + } + + protected override async Task CheckAsync(EvaluationMetadata metadata) + { + var value = metadata.Value; + var exception = metadata.Exception; + + if (exception != null) + { + return AssertionResult.Failed($"threw {exception.GetType().FullName}"); + } + + var result = await value!.IsPositiveAsync(); + return result + ? AssertionResult.Passed + : AssertionResult.Failed($"found {value}"); + } + + protected override string GetExpectation() + { + return "to satisfy IsPositiveAsync"; + } +} + +/// +/// Generated assertion for IsGreaterThanAsync +/// +public sealed class Int_IsGreaterThanAsync_Int_Assertion : Assertion +{ + private readonly int _threshold; + + public Int_IsGreaterThanAsync_Int_Assertion(AssertionContext context, int threshold) + : base(context) + { + _threshold = threshold; + } + + protected override async Task CheckAsync(EvaluationMetadata metadata) + { + var value = metadata.Value; + var exception = metadata.Exception; + + if (exception != null) + { + return AssertionResult.Failed($"threw {exception.GetType().FullName}"); + } + + var result = await value!.IsGreaterThanAsync(_threshold); + return result + ? AssertionResult.Passed + : AssertionResult.Failed($"found {value}"); + } + + protected override string GetExpectation() + { + return $"to satisfy IsGreaterThanAsync({_threshold})"; + } +} + +public static partial class AsyncBoolAssertionExtensions +{ + /// + /// Generated extension method for IsPositiveAsync + /// + public static Int_IsPositiveAsync_Assertion IsPositiveAsync(this IAssertionSource source) + { + source.Context.ExpressionBuilder.Append(".IsPositiveAsync()"); + return new Int_IsPositiveAsync_Assertion(source.Context); + } + + /// + /// Generated extension method for IsGreaterThanAsync + /// + public static Int_IsGreaterThanAsync_Int_Assertion IsGreaterThanAsync(this IAssertionSource source, int threshold, [CallerArgumentExpression(nameof(threshold))] string? thresholdExpression = null) + { + source.Context.ExpressionBuilder.Append($".IsGreaterThanAsync({thresholdExpression})"); + return new Int_IsGreaterThanAsync_Int_Assertion(source.Context, threshold); + } + +} + +] \ No newline at end of file diff --git a/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_GeneratesValidCSharp.DotNet9_0.verified.txt b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_GeneratesValidCSharp.DotNet9_0.verified.txt new file mode 100644 index 0000000000..01be921f77 --- /dev/null +++ b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_GeneratesValidCSharp.DotNet9_0.verified.txt @@ -0,0 +1,103 @@ +[ +// +#pragma warning disable +#nullable enable + +using System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using TUnit.Assertions.Core; +using TUnit.Assertions.Tests.TestData; + +namespace TUnit.Assertions.Extensions; + +/// +/// Generated assertion for IsPositiveAsync +/// +public sealed class Int_IsPositiveAsync_Assertion : Assertion +{ + public Int_IsPositiveAsync_Assertion(AssertionContext context) + : base(context) + { + } + + protected override async Task CheckAsync(EvaluationMetadata metadata) + { + var value = metadata.Value; + var exception = metadata.Exception; + + if (exception != null) + { + return AssertionResult.Failed($"threw {exception.GetType().FullName}"); + } + + var result = await value!.IsPositiveAsync(); + return result + ? AssertionResult.Passed + : AssertionResult.Failed($"found {value}"); + } + + protected override string GetExpectation() + { + return "to satisfy IsPositiveAsync"; + } +} + +/// +/// Generated assertion for IsGreaterThanAsync +/// +public sealed class Int_IsGreaterThanAsync_Int_Assertion : Assertion +{ + private readonly int _threshold; + + public Int_IsGreaterThanAsync_Int_Assertion(AssertionContext context, int threshold) + : base(context) + { + _threshold = threshold; + } + + protected override async Task CheckAsync(EvaluationMetadata metadata) + { + var value = metadata.Value; + var exception = metadata.Exception; + + if (exception != null) + { + return AssertionResult.Failed($"threw {exception.GetType().FullName}"); + } + + var result = await value!.IsGreaterThanAsync(_threshold); + return result + ? AssertionResult.Passed + : AssertionResult.Failed($"found {value}"); + } + + protected override string GetExpectation() + { + return $"to satisfy IsGreaterThanAsync({_threshold})"; + } +} + +public static partial class AsyncBoolAssertionExtensions +{ + /// + /// Generated extension method for IsPositiveAsync + /// + public static Int_IsPositiveAsync_Assertion IsPositiveAsync(this IAssertionSource source) + { + source.Context.ExpressionBuilder.Append(".IsPositiveAsync()"); + return new Int_IsPositiveAsync_Assertion(source.Context); + } + + /// + /// Generated extension method for IsGreaterThanAsync + /// + public static Int_IsGreaterThanAsync_Int_Assertion IsGreaterThanAsync(this IAssertionSource source, int threshold, [CallerArgumentExpression(nameof(threshold))] string? thresholdExpression = null) + { + source.Context.ExpressionBuilder.Append($".IsGreaterThanAsync({thresholdExpression})"); + return new Int_IsGreaterThanAsync_Int_Assertion(source.Context, threshold); + } + +} + +] \ No newline at end of file diff --git a/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_GeneratesValidCSharp.Net4_7.verified.txt b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_GeneratesValidCSharp.Net4_7.verified.txt new file mode 100644 index 0000000000..01be921f77 --- /dev/null +++ b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_GeneratesValidCSharp.Net4_7.verified.txt @@ -0,0 +1,103 @@ +[ +// +#pragma warning disable +#nullable enable + +using System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using TUnit.Assertions.Core; +using TUnit.Assertions.Tests.TestData; + +namespace TUnit.Assertions.Extensions; + +/// +/// Generated assertion for IsPositiveAsync +/// +public sealed class Int_IsPositiveAsync_Assertion : Assertion +{ + public Int_IsPositiveAsync_Assertion(AssertionContext context) + : base(context) + { + } + + protected override async Task CheckAsync(EvaluationMetadata metadata) + { + var value = metadata.Value; + var exception = metadata.Exception; + + if (exception != null) + { + return AssertionResult.Failed($"threw {exception.GetType().FullName}"); + } + + var result = await value!.IsPositiveAsync(); + return result + ? AssertionResult.Passed + : AssertionResult.Failed($"found {value}"); + } + + protected override string GetExpectation() + { + return "to satisfy IsPositiveAsync"; + } +} + +/// +/// Generated assertion for IsGreaterThanAsync +/// +public sealed class Int_IsGreaterThanAsync_Int_Assertion : Assertion +{ + private readonly int _threshold; + + public Int_IsGreaterThanAsync_Int_Assertion(AssertionContext context, int threshold) + : base(context) + { + _threshold = threshold; + } + + protected override async Task CheckAsync(EvaluationMetadata metadata) + { + var value = metadata.Value; + var exception = metadata.Exception; + + if (exception != null) + { + return AssertionResult.Failed($"threw {exception.GetType().FullName}"); + } + + var result = await value!.IsGreaterThanAsync(_threshold); + return result + ? AssertionResult.Passed + : AssertionResult.Failed($"found {value}"); + } + + protected override string GetExpectation() + { + return $"to satisfy IsGreaterThanAsync({_threshold})"; + } +} + +public static partial class AsyncBoolAssertionExtensions +{ + /// + /// Generated extension method for IsPositiveAsync + /// + public static Int_IsPositiveAsync_Assertion IsPositiveAsync(this IAssertionSource source) + { + source.Context.ExpressionBuilder.Append(".IsPositiveAsync()"); + return new Int_IsPositiveAsync_Assertion(source.Context); + } + + /// + /// Generated extension method for IsGreaterThanAsync + /// + public static Int_IsGreaterThanAsync_Int_Assertion IsGreaterThanAsync(this IAssertionSource source, int threshold, [CallerArgumentExpression(nameof(threshold))] string? thresholdExpression = null) + { + source.Context.ExpressionBuilder.Append($".IsGreaterThanAsync({thresholdExpression})"); + return new Int_IsGreaterThanAsync_Int_Assertion(source.Context, threshold); + } + +} + +] \ No newline at end of file diff --git a/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_ProducesNoCS1591.DotNet10_0.verified.txt b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_ProducesNoCS1591.DotNet10_0.verified.txt index ed3acbadf3..01be921f77 100644 --- a/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_ProducesNoCS1591.DotNet10_0.verified.txt +++ b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_ProducesNoCS1591.DotNet10_0.verified.txt @@ -34,7 +34,7 @@ public sealed class Int_IsPositiveAsync_Assertion : Assertion var result = await value!.IsPositiveAsync(); return result ? AssertionResult.Passed - : AssertionResult.Failed($"found {value}")); + : AssertionResult.Failed($"found {value}"); } protected override string GetExpectation() @@ -69,7 +69,7 @@ public sealed class Int_IsGreaterThanAsync_Int_Assertion : Assertion var result = await value!.IsGreaterThanAsync(_threshold); return result ? AssertionResult.Passed - : AssertionResult.Failed($"found {value}")); + : AssertionResult.Failed($"found {value}"); } protected override string GetExpectation() diff --git a/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_ProducesNoCS1591.DotNet8_0.verified.txt b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_ProducesNoCS1591.DotNet8_0.verified.txt index ed3acbadf3..01be921f77 100644 --- a/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_ProducesNoCS1591.DotNet8_0.verified.txt +++ b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_ProducesNoCS1591.DotNet8_0.verified.txt @@ -34,7 +34,7 @@ public sealed class Int_IsPositiveAsync_Assertion : Assertion var result = await value!.IsPositiveAsync(); return result ? AssertionResult.Passed - : AssertionResult.Failed($"found {value}")); + : AssertionResult.Failed($"found {value}"); } protected override string GetExpectation() @@ -69,7 +69,7 @@ public sealed class Int_IsGreaterThanAsync_Int_Assertion : Assertion var result = await value!.IsGreaterThanAsync(_threshold); return result ? AssertionResult.Passed - : AssertionResult.Failed($"found {value}")); + : AssertionResult.Failed($"found {value}"); } protected override string GetExpectation() diff --git a/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_ProducesNoCS1591.DotNet9_0.verified.txt b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_ProducesNoCS1591.DotNet9_0.verified.txt index ed3acbadf3..01be921f77 100644 --- a/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_ProducesNoCS1591.DotNet9_0.verified.txt +++ b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_ProducesNoCS1591.DotNet9_0.verified.txt @@ -34,7 +34,7 @@ public sealed class Int_IsPositiveAsync_Assertion : Assertion var result = await value!.IsPositiveAsync(); return result ? AssertionResult.Passed - : AssertionResult.Failed($"found {value}")); + : AssertionResult.Failed($"found {value}"); } protected override string GetExpectation() @@ -69,7 +69,7 @@ public sealed class Int_IsGreaterThanAsync_Int_Assertion : Assertion var result = await value!.IsGreaterThanAsync(_threshold); return result ? AssertionResult.Passed - : AssertionResult.Failed($"found {value}")); + : AssertionResult.Failed($"found {value}"); } protected override string GetExpectation() diff --git a/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_ProducesNoCS1591.Net4_7.verified.txt b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_ProducesNoCS1591.Net4_7.verified.txt index ed3acbadf3..01be921f77 100644 --- a/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_ProducesNoCS1591.Net4_7.verified.txt +++ b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.AsyncBoolAssertion_ProducesNoCS1591.Net4_7.verified.txt @@ -34,7 +34,7 @@ public sealed class Int_IsPositiveAsync_Assertion : Assertion var result = await value!.IsPositiveAsync(); return result ? AssertionResult.Passed - : AssertionResult.Failed($"found {value}")); + : AssertionResult.Failed($"found {value}"); } protected override string GetExpectation() @@ -69,7 +69,7 @@ public sealed class Int_IsGreaterThanAsync_Int_Assertion : Assertion var result = await value!.IsGreaterThanAsync(_threshold); return result ? AssertionResult.Passed - : AssertionResult.Failed($"found {value}")); + : AssertionResult.Failed($"found {value}"); } protected override string GetExpectation() diff --git a/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.cs b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.cs index c6f4ee3a97..130eeb5002 100644 --- a/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.cs +++ b/TUnit.Assertions.SourceGenerator.Tests/XmlDocsRegressionTests.cs @@ -21,6 +21,15 @@ internal class XmlDocsRegressionTests : TestsBase [Test] public Task MethodWithComparableConstraint_ProducesNoCS1591() => AssertNoCS1591("MethodWithComparableConstraint.cs"); + // Compile-clean regression tests: parse and compile the generated source through Roslyn, + // then assert the diagnostic stream contains no error-severity entries. The CS1591 checks + // above are too narrow to catch emit-syntax bugs (extra punctuation, mis-paired brackets, + // wrong default-value rendering); these tests close that gap by failing fast on any + // compiler error in the generated code regardless of its specific diagnostic id. + + [Test] + public Task AsyncBoolAssertion_GeneratesValidCSharp() => AssertNoCompilationErrors("AsyncBoolAssertion.cs"); + private Task AssertNoCS1591(string testDataFile) => RunTest( Path.Combine(Sourcy.Git.RootDirectory.FullName, "TUnit.Assertions.SourceGenerator.Tests", @@ -48,4 +57,40 @@ private Task AssertNoCS1591(string testDataFile) => RunTest( await Assert.That(cs1591).IsEmpty(); }); + + private Task AssertNoCompilationErrors(string testDataFile) => RunTest( + Path.Combine(Sourcy.Git.RootDirectory.FullName, + "TUnit.Assertions.SourceGenerator.Tests", + "TestData", + testDataFile), + async generatedFiles => + { + await Assert.That(generatedFiles).IsNotEmpty(); + + var trees = generatedFiles + .Select(source => CSharpSyntaxTree.ParseText(source)) + .ToArray(); + + var compilation = CSharpCompilation.Create( + "CompileCheck", + trees, + ReferencesHelper.References, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + // On the net472 leg of CI, the Polyfill assembly's CallerArgumentExpressionAttribute + // is declared internal, which produces a CS0122 ('inaccessible due to its protection + // level') false positive when Roslyn compiles the generator's output through the test + // project's reference set. Filter CS0122 only on net472; the emit shape is still + // pinned by the `.Net4_7` snapshot files. On modern TFMs the BCL attribute is public, + // so CS0122 (if it ever appears) would be a genuine signal and is not filtered. + var errors = compilation.GetDiagnostics() + .Where(d => d.Severity == DiagnosticSeverity.Error) +#if NETFRAMEWORK + .Where(d => !string.Equals(d.Id, "CS0122", StringComparison.Ordinal)) +#endif + .Select(d => $"{d.Id}: {d.GetMessage()}") + .ToArray(); + + await Assert.That(errors).IsEmpty(); + }); } diff --git a/TUnit.Assertions.SourceGenerator/Generators/MethodAssertionGenerator.cs b/TUnit.Assertions.SourceGenerator/Generators/MethodAssertionGenerator.cs index c5895e618e..3d3db7de51 100644 --- a/TUnit.Assertions.SourceGenerator/Generators/MethodAssertionGenerator.cs +++ b/TUnit.Assertions.SourceGenerator/Generators/MethodAssertionGenerator.cs @@ -840,7 +840,7 @@ private static void GenerateMethodCall(StringBuilder sb, AssertionMethodData dat sb.AppendLine($" var result = await {methodCall};"); sb.AppendLine(" return result"); sb.AppendLine(" ? AssertionResult.Passed"); - sb.AppendLine(" : AssertionResult.Failed($\"found {value}\"));"); + sb.AppendLine(" : AssertionResult.Failed($\"found {value}\");"); break; case ReturnTypeKind.TaskAssertionResult: