From c6b66360f991ef389fcf4fd515268defb803fd54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Fri, 31 Jul 2026 08:02:41 +0200 Subject: [PATCH] test: pin pending-task returns and abstract-indexer generation Add two regression tests prompted by TUnit issues #6515 and #6516: - Returns(() => tcs.Task) must hand the pending task to the caller as-is, so it can be raced against timeouts or cancellation. - Mocking an abstract class with abstract indexers must not emit base[...] calls (would be CS0205). --- .../MockTests.ClassTests.IndexerTests.cs | 32 +++++++++++++++++++ .../ReturnsThrowsAsyncExtensionsTests.cs | 15 +++++++++ 2 files changed, 47 insertions(+) diff --git a/Tests/Mockolate.SourceGenerators.Tests/MockTests.ClassTests.IndexerTests.cs b/Tests/Mockolate.SourceGenerators.Tests/MockTests.ClassTests.IndexerTests.cs index 2d627512..41388399 100644 --- a/Tests/Mockolate.SourceGenerators.Tests/MockTests.ClassTests.IndexerTests.cs +++ b/Tests/Mockolate.SourceGenerators.Tests/MockTests.ClassTests.IndexerTests.cs @@ -470,6 +470,38 @@ public override int this[int index] """).IgnoringNewlineStyle(); } + [Fact] + public async Task ShouldNotCallBaseForAbstractIndexersOfAbstractClasses() + { + GeneratorResult result = Generator + .Run(""" + using Mockolate; + + namespace MyCode; + public class Program + { + public static void Main(string[] args) + { + _ = MyAbstractService.CreateMock(); + } + } + + public abstract class MyAbstractService + { + public abstract object this[int index] { get; } + public abstract int this[string key] { get; set; } + } + """); + + await That(result.Diagnostics).IsEmpty(); + await That(result.Sources).ContainsKey("Mock.MyAbstractService.g.cs"); + await That(result.Sources["Mock.MyAbstractService.g.cs"]) + .Contains("public override object this[int index]").And + .Contains("public override int this[string key]").And + .DoesNotContain("base[") + .Because("abstract indexers have no base implementation to call (CS0205)"); + } + [Fact] public async Task ShouldSupportSpanAndReadOnlySpanIndexerParameters() { diff --git a/Tests/Mockolate.Tests/ReturnsThrowsAsyncExtensionsTests.cs b/Tests/Mockolate.Tests/ReturnsThrowsAsyncExtensionsTests.cs index b397ca81..985df3ed 100644 --- a/Tests/Mockolate.Tests/ReturnsThrowsAsyncExtensionsTests.cs +++ b/Tests/Mockolate.Tests/ReturnsThrowsAsyncExtensionsTests.cs @@ -317,6 +317,21 @@ public async Task ReturnsAsync_WithParameters_ReturnsConfiguredValue() await That(result).IsEqualTo(42); } + + [Fact] + public async Task Returns_TaskFactory_ShouldReturnPendingTaskAsIs() + { + TaskCompletionSource completionSource = new(); + IReturnsAsyncExtensionsSetupTest sut = IReturnsAsyncExtensionsSetupTest.CreateMock(); + sut.Mock.Setup.Method0().Returns(() => completionSource.Task); + + Task result = sut.Method0(); + + await That(result.IsCompleted).IsFalse() + .Because("the factory's task must be handed to the caller as-is, so it can be raced against timeouts or cancellation"); + completionSource.SetResult(42); + await That(await result).IsEqualTo(42); + } } #if NET8_0_OR_GREATER