From 9428146798fb3fb064adc1446b2caa6dd9536ebf Mon Sep 17 00:00:00 2001 From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com> Date: Sun, 23 Aug 2026 14:41:26 +0100 Subject: [PATCH 1/2] fix: disambiguate generated property lookup Filter generated PropertyInfo lookups by return type so covariant overrides do not throw AmbiguousMatchException.\n\nCloses #6657 --- .../Utilities/MetadataGenerationHelper.cs | 9 ++- .../Bugs/6657/Tests6657.cs | 13 ++++ .../ClassConstructorTest.Test.verified.txt | 2 +- ...pleDataSourceDrivenTests.Test.verified.txt | 8 +- .../CustomDisplayNameTests.Test.verified.txt | 2 +- ...aSource_Should_Generate_Tests.verified.txt | 4 +- ...ritedPropertySetterTests.Test.verified.txt | 16 ++-- .../InheritsTestsTests.Test.verified.txt | 2 +- .../PropertySetterTests.Test.verified.txt | 16 ++-- .../Tests6657.Test.verified.txt | 77 +++++++++++++++++++ tests/TUnit.TestProject/Bugs/6657/Tests.cs | 22 ++++++ 11 files changed, 144 insertions(+), 27 deletions(-) create mode 100644 tests/TUnit.Core.SourceGenerator.Tests/Bugs/6657/Tests6657.cs create mode 100644 tests/TUnit.Core.SourceGenerator.Tests/Tests6657.Test.verified.txt create mode 100644 tests/TUnit.TestProject/Bugs/6657/Tests.cs diff --git a/src/TUnit.Core.SourceGenerator/Utilities/MetadataGenerationHelper.cs b/src/TUnit.Core.SourceGenerator/Utilities/MetadataGenerationHelper.cs index 213f460c9ab..27aa25d3eb0 100644 --- a/src/TUnit.Core.SourceGenerator/Utilities/MetadataGenerationHelper.cs +++ b/src/TUnit.Core.SourceGenerator/Utilities/MetadataGenerationHelper.cs @@ -301,7 +301,8 @@ public static void WritePropertyMetadata(ICodeWriter writer, IPropertySymbol pro { var safeTypeNameForReflection = containingType.GloballyQualified(); // For type parameters, we need to use typeof(object) instead of typeof(T) - var safePropertyTypeName = CodeGenerationHelpers.ContainsTypeParameter(property.Type) ? "object" : property.Type.GloballyQualified(); + var containsTypeParameter = CodeGenerationHelpers.ContainsTypeParameter(property.Type); + var safePropertyTypeName = containsTypeParameter ? "object" : property.Type.GloballyQualified(); writer.AppendLine("new global::TUnit.Core.PropertyMetadata"); writer.AppendLine("{"); @@ -310,7 +311,11 @@ public static void WritePropertyMetadata(ICodeWriter writer, IPropertySymbol pro var currentIndent = writer.IndentLevel; writer.SetIndentLevel(currentIndent + 1); - writer.AppendLine($"ReflectionInfo = typeof({safeTypeNameForReflection}).GetProperty(\"{property.Name}\"),"); + var reflectionInfo = containsTypeParameter + ? $"typeof({safeTypeNameForReflection}).GetProperty(\"{property.Name}\")" + : $"typeof({safeTypeNameForReflection}).GetProperty(\"{property.Name}\", typeof({safePropertyTypeName}))"; + + writer.AppendLine($"ReflectionInfo = {reflectionInfo},"); writer.AppendLine($"Type = typeof({safePropertyTypeName}),"); writer.AppendLine($"Name = \"{property.Name}\","); writer.AppendLine($"IsStatic = {property.IsStatic.ToString().ToLower()},"); diff --git a/tests/TUnit.Core.SourceGenerator.Tests/Bugs/6657/Tests6657.cs b/tests/TUnit.Core.SourceGenerator.Tests/Bugs/6657/Tests6657.cs new file mode 100644 index 00000000000..7bc038dc0f7 --- /dev/null +++ b/tests/TUnit.Core.SourceGenerator.Tests/Bugs/6657/Tests6657.cs @@ -0,0 +1,13 @@ +namespace TUnit.Core.SourceGenerator.Tests; + +internal class Tests6657 : TestsBase +{ + [Test] + public Task Test() => RunTest(Path.Combine( + Git.TestsDirectory.FullName, + "TUnit.TestProject", + "Bugs", + "6657", + "Tests.cs"), + _ => Task.CompletedTask); +} diff --git a/tests/TUnit.Core.SourceGenerator.Tests/ClassConstructorTest.Test.verified.txt b/tests/TUnit.Core.SourceGenerator.Tests/ClassConstructorTest.Test.verified.txt index 2f47fd519e6..ec4ec9c8787 100644 --- a/tests/TUnit.Core.SourceGenerator.Tests/ClassConstructorTest.Test.verified.txt +++ b/tests/TUnit.Core.SourceGenerator.Tests/ClassConstructorTest.Test.verified.txt @@ -22,7 +22,7 @@ internal static class TUnit_TestProject_ClassConstructorTest__TestSource { new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.ClassConstructorTest).GetProperty("DummyReferenceTypeClass"), + ReflectionInfo = typeof(global::TUnit.TestProject.ClassConstructorTest).GetProperty("DummyReferenceTypeClass", typeof(global::TUnit.TestProject.DummyReferenceTypeClass)), Type = typeof(global::TUnit.TestProject.DummyReferenceTypeClass), Name = "DummyReferenceTypeClass", IsStatic = false, diff --git a/tests/TUnit.Core.SourceGenerator.Tests/ClassTupleDataSourceDrivenTests.Test.verified.txt b/tests/TUnit.Core.SourceGenerator.Tests/ClassTupleDataSourceDrivenTests.Test.verified.txt index c81af297f91..c6d9805af94 100644 --- a/tests/TUnit.Core.SourceGenerator.Tests/ClassTupleDataSourceDrivenTests.Test.verified.txt +++ b/tests/TUnit.Core.SourceGenerator.Tests/ClassTupleDataSourceDrivenTests.Test.verified.txt @@ -34,7 +34,7 @@ internal static class TUnit_TestProject_ClassTupleDataSourceDrivenTests__TestSou { new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.ClassTupleDataSourceDrivenTests).GetProperty("Property1"), + ReflectionInfo = typeof(global::TUnit.TestProject.ClassTupleDataSourceDrivenTests).GetProperty("Property1", typeof(global::System.ValueTuple)), Type = typeof(global::System.ValueTuple), Name = "Property1", IsStatic = false, @@ -45,7 +45,7 @@ internal static class TUnit_TestProject_ClassTupleDataSourceDrivenTests__TestSou }, new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.ClassTupleDataSourceDrivenTests).GetProperty("Property2"), + ReflectionInfo = typeof(global::TUnit.TestProject.ClassTupleDataSourceDrivenTests).GetProperty("Property2", typeof(global::System.ValueTuple)), Type = typeof(global::System.ValueTuple), Name = "Property2", IsStatic = false, @@ -56,7 +56,7 @@ internal static class TUnit_TestProject_ClassTupleDataSourceDrivenTests__TestSou }, new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.ClassTupleDataSourceDrivenTests).GetProperty("Property3"), + ReflectionInfo = typeof(global::TUnit.TestProject.ClassTupleDataSourceDrivenTests).GetProperty("Property3", typeof(global::System.ValueTuple)), Type = typeof(global::System.ValueTuple), Name = "Property3", IsStatic = false, @@ -67,7 +67,7 @@ internal static class TUnit_TestProject_ClassTupleDataSourceDrivenTests__TestSou }, new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.ClassTupleDataSourceDrivenTests).GetProperty("Property4"), + ReflectionInfo = typeof(global::TUnit.TestProject.ClassTupleDataSourceDrivenTests).GetProperty("Property4", typeof(global::System.ValueTuple)), Type = typeof(global::System.ValueTuple), Name = "Property4", IsStatic = false, diff --git a/tests/TUnit.Core.SourceGenerator.Tests/CustomDisplayNameTests.Test.verified.txt b/tests/TUnit.Core.SourceGenerator.Tests/CustomDisplayNameTests.Test.verified.txt index 4f0f97a1427..f2df7650955 100644 --- a/tests/TUnit.Core.SourceGenerator.Tests/CustomDisplayNameTests.Test.verified.txt +++ b/tests/TUnit.Core.SourceGenerator.Tests/CustomDisplayNameTests.Test.verified.txt @@ -19,7 +19,7 @@ internal static class TUnit_TestProject_CustomDisplayNameTests__TestSource { new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.CustomDisplayNameTests).GetProperty("Order"), + ReflectionInfo = typeof(global::TUnit.TestProject.CustomDisplayNameTests).GetProperty("Order", typeof(int)), Type = typeof(int), Name = "Order", IsStatic = false, diff --git a/tests/TUnit.Core.SourceGenerator.Tests/GenericMethodWithDataSourceTests.Generic_Method_With_MethodDataSource_Should_Generate_Tests.verified.txt b/tests/TUnit.Core.SourceGenerator.Tests/GenericMethodWithDataSourceTests.Generic_Method_With_MethodDataSource_Should_Generate_Tests.verified.txt index 5237c4b2b04..2446df97e90 100644 --- a/tests/TUnit.Core.SourceGenerator.Tests/GenericMethodWithDataSourceTests.Generic_Method_With_MethodDataSource_Should_Generate_Tests.verified.txt +++ b/tests/TUnit.Core.SourceGenerator.Tests/GenericMethodWithDataSourceTests.Generic_Method_With_MethodDataSource_Should_Generate_Tests.verified.txt @@ -1114,7 +1114,7 @@ internal static class TUnit_TestProject_Bugs__4431_GenericClassWithClassDataSour { new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.Bugs._4431.GenericClassWithClassDataSource<>).GetProperty("DataSource"), + ReflectionInfo = typeof(global::TUnit.TestProject.Bugs._4431.GenericClassWithClassDataSource<>).GetProperty("DataSource", typeof(global::TUnit.TestProject.Bugs._4431.TestDataSource)), Type = typeof(global::TUnit.TestProject.Bugs._4431.TestDataSource), Name = "DataSource", IsStatic = false, @@ -1240,7 +1240,7 @@ internal static class TUnit_TestProject_Bugs__4431_GenericClassGenericMethodWith { new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.Bugs._4431.GenericClassGenericMethodWithDataSources<>).GetProperty("DataSource"), + ReflectionInfo = typeof(global::TUnit.TestProject.Bugs._4431.GenericClassGenericMethodWithDataSources<>).GetProperty("DataSource", typeof(global::TUnit.TestProject.Bugs._4431.TestDataSource)), Type = typeof(global::TUnit.TestProject.Bugs._4431.TestDataSource), Name = "DataSource", IsStatic = false, diff --git a/tests/TUnit.Core.SourceGenerator.Tests/InheritedPropertySetterTests.Test.verified.txt b/tests/TUnit.Core.SourceGenerator.Tests/InheritedPropertySetterTests.Test.verified.txt index 99ee7f6758d..80ab190d679 100644 --- a/tests/TUnit.Core.SourceGenerator.Tests/InheritedPropertySetterTests.Test.verified.txt +++ b/tests/TUnit.Core.SourceGenerator.Tests/InheritedPropertySetterTests.Test.verified.txt @@ -33,7 +33,7 @@ internal static class TUnit_TestProject_PropertySetterTests__TestSource { new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property1"), + ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property1", typeof(string)), Type = typeof(string), Name = "Property1", IsStatic = false, @@ -44,7 +44,7 @@ internal static class TUnit_TestProject_PropertySetterTests__TestSource }, new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property2"), + ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property2", typeof(string)), Type = typeof(string), Name = "Property2", IsStatic = false, @@ -55,7 +55,7 @@ internal static class TUnit_TestProject_PropertySetterTests__TestSource }, new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property3"), + ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property3", typeof(global::TUnit.TestProject.PropertySetterTests.InnerModel)), Type = typeof(global::TUnit.TestProject.PropertySetterTests.InnerModel), Name = "Property3", IsStatic = false, @@ -66,7 +66,7 @@ internal static class TUnit_TestProject_PropertySetterTests__TestSource }, new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property4"), + ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property4", typeof(global::TUnit.TestProject.PropertySetterTests.InnerModel)), Type = typeof(global::TUnit.TestProject.PropertySetterTests.InnerModel), Name = "Property4", IsStatic = false, @@ -77,7 +77,7 @@ internal static class TUnit_TestProject_PropertySetterTests__TestSource }, new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property5"), + ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property5", typeof(global::TUnit.TestProject.PropertySetterTests.InnerModel)), Type = typeof(global::TUnit.TestProject.PropertySetterTests.InnerModel), Name = "Property5", IsStatic = false, @@ -88,7 +88,7 @@ internal static class TUnit_TestProject_PropertySetterTests__TestSource }, new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property6"), + ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property6", typeof(global::TUnit.TestProject.PropertySetterTests.InnerModel)), Type = typeof(global::TUnit.TestProject.PropertySetterTests.InnerModel), Name = "Property6", IsStatic = false, @@ -99,7 +99,7 @@ internal static class TUnit_TestProject_PropertySetterTests__TestSource }, new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property7"), + ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property7", typeof(string)), Type = typeof(string), Name = "Property7", IsStatic = false, @@ -110,7 +110,7 @@ internal static class TUnit_TestProject_PropertySetterTests__TestSource }, new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("StaticProperty"), + ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("StaticProperty", typeof(global::TUnit.TestProject.PropertySetterTests.StaticInnerModel)), Type = typeof(global::TUnit.TestProject.PropertySetterTests.StaticInnerModel), Name = "StaticProperty", IsStatic = true, diff --git a/tests/TUnit.Core.SourceGenerator.Tests/InheritsTestsTests.Test.verified.txt b/tests/TUnit.Core.SourceGenerator.Tests/InheritsTestsTests.Test.verified.txt index 84b60386bc2..903d3cad3ee 100644 --- a/tests/TUnit.Core.SourceGenerator.Tests/InheritsTestsTests.Test.verified.txt +++ b/tests/TUnit.Core.SourceGenerator.Tests/InheritsTestsTests.Test.verified.txt @@ -23,7 +23,7 @@ internal static class TUnit_TestProject_Bugs__1924_None_BaseClass__TestSource { new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.Bugs._1924.None.BaseClass).GetProperty("Data"), + ReflectionInfo = typeof(global::TUnit.TestProject.Bugs._1924.None.BaseClass).GetProperty("Data", typeof(global::TUnit.TestProject.Bugs._1924.DataClass)), Type = typeof(global::TUnit.TestProject.Bugs._1924.DataClass), Name = "Data", IsStatic = false, diff --git a/tests/TUnit.Core.SourceGenerator.Tests/PropertySetterTests.Test.verified.txt b/tests/TUnit.Core.SourceGenerator.Tests/PropertySetterTests.Test.verified.txt index aa4e6090171..023b3768f2e 100644 --- a/tests/TUnit.Core.SourceGenerator.Tests/PropertySetterTests.Test.verified.txt +++ b/tests/TUnit.Core.SourceGenerator.Tests/PropertySetterTests.Test.verified.txt @@ -33,7 +33,7 @@ internal static class TUnit_TestProject_PropertySetterTests__TestSource { new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property1"), + ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property1", typeof(string)), Type = typeof(string), Name = "Property1", IsStatic = false, @@ -44,7 +44,7 @@ internal static class TUnit_TestProject_PropertySetterTests__TestSource }, new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property2"), + ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property2", typeof(string)), Type = typeof(string), Name = "Property2", IsStatic = false, @@ -55,7 +55,7 @@ internal static class TUnit_TestProject_PropertySetterTests__TestSource }, new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property3"), + ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property3", typeof(global::TUnit.TestProject.PropertySetterTests.InnerModel)), Type = typeof(global::TUnit.TestProject.PropertySetterTests.InnerModel), Name = "Property3", IsStatic = false, @@ -66,7 +66,7 @@ internal static class TUnit_TestProject_PropertySetterTests__TestSource }, new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property4"), + ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property4", typeof(global::TUnit.TestProject.PropertySetterTests.InnerModel)), Type = typeof(global::TUnit.TestProject.PropertySetterTests.InnerModel), Name = "Property4", IsStatic = false, @@ -77,7 +77,7 @@ internal static class TUnit_TestProject_PropertySetterTests__TestSource }, new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property5"), + ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property5", typeof(global::TUnit.TestProject.PropertySetterTests.InnerModel)), Type = typeof(global::TUnit.TestProject.PropertySetterTests.InnerModel), Name = "Property5", IsStatic = false, @@ -88,7 +88,7 @@ internal static class TUnit_TestProject_PropertySetterTests__TestSource }, new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property6"), + ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property6", typeof(global::TUnit.TestProject.PropertySetterTests.InnerModel)), Type = typeof(global::TUnit.TestProject.PropertySetterTests.InnerModel), Name = "Property6", IsStatic = false, @@ -99,7 +99,7 @@ internal static class TUnit_TestProject_PropertySetterTests__TestSource }, new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property7"), + ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("Property7", typeof(string)), Type = typeof(string), Name = "Property7", IsStatic = false, @@ -110,7 +110,7 @@ internal static class TUnit_TestProject_PropertySetterTests__TestSource }, new global::TUnit.Core.PropertyMetadata { - ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("StaticProperty"), + ReflectionInfo = typeof(global::TUnit.TestProject.PropertySetterTests).GetProperty("StaticProperty", typeof(global::TUnit.TestProject.PropertySetterTests.StaticInnerModel)), Type = typeof(global::TUnit.TestProject.PropertySetterTests.StaticInnerModel), Name = "StaticProperty", IsStatic = true, diff --git a/tests/TUnit.Core.SourceGenerator.Tests/Tests6657.Test.verified.txt b/tests/TUnit.Core.SourceGenerator.Tests/Tests6657.Test.verified.txt new file mode 100644 index 00000000000..eb3d3d1e16c --- /dev/null +++ b/tests/TUnit.Core.SourceGenerator.Tests/Tests6657.Test.verified.txt @@ -0,0 +1,77 @@ +// +#pragma warning disable + +#nullable enable +namespace TUnit.Generated; +[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute] +[global::System.CodeDom.Compiler.GeneratedCode("TUnit", "VERSION_SCRUBBED")] +internal static class TUnit_TestProject_Bugs__6657_CovariantPropertyOverrideTests_InheritedTest_TestSource +{ + private static readonly global::TUnit.Core.ClassMetadata __classMetadata = global::TUnit.Core.ClassMetadata.GetOrAdd("TestsBase`1:global::TUnit.TestProject.Bugs._6657.CovariantPropertyOverrideTests", new global::TUnit.Core.ClassMetadata + { + Type = typeof(global::TUnit.TestProject.Bugs._6657.CovariantPropertyOverrideTests), + TypeInfo = new global::TUnit.Core.ConcreteType(typeof(global::TUnit.TestProject.Bugs._6657.CovariantPropertyOverrideTests)), + Name = "CovariantPropertyOverrideTests", + Namespace = "TUnit.TestProject.Bugs._6657", + Assembly = global::TUnit.Core.AssemblyMetadata.GetOrAdd("TestsBase`1", "TestsBase`1"), + Parameters = global::System.Array.Empty(), + Properties = new global::TUnit.Core.PropertyMetadata[] + { + new global::TUnit.Core.PropertyMetadata + { + ReflectionInfo = typeof(global::TUnit.TestProject.Bugs._6657.CovariantPropertyOverrideTests).GetProperty("Thing", typeof(global::TUnit.TestProject.Bugs._6657.Thing)), + Type = typeof(global::TUnit.TestProject.Bugs._6657.Thing), + Name = "Thing", + IsStatic = false, + IsNullable = false, + Getter = o => ((global::TUnit.TestProject.Bugs._6657.CovariantPropertyOverrideTests)o).Thing, + ClassMetadata = null!, + ContainingTypeMetadata = null! + } + }, + Parent = null + }); + private static readonly global::System.Type __classType = typeof(global::TUnit.TestProject.Bugs._6657.CovariantPropertyOverrideTests); + private static readonly global::TUnit.Core.MethodMetadata __mm_0 = global::TUnit.Core.MethodMetadataFactory.Create("InheritedTest", __classType, typeof(global::System.Threading.Tasks.Task), __classMetadata); + private static global::TUnit.TestProject.Bugs._6657.CovariantPropertyOverrideTests __CreateInstance_0(global::System.Type[] typeArgs, object?[] args) + { + return new global::TUnit.TestProject.Bugs._6657.CovariantPropertyOverrideTests(); + } + private static global::System.Threading.Tasks.ValueTask __Invoke_0(global::TUnit.TestProject.Bugs._6657.CovariantPropertyOverrideTests instance, int methodIndex, object?[] args, global::System.Threading.CancellationToken cancellationToken) + { + try + { + return new global::System.Threading.Tasks.ValueTask(instance.InheritedTest()); + } + catch (global::System.Exception ex) + { + return new global::System.Threading.Tasks.ValueTask(global::System.Threading.Tasks.Task.FromException(ex)); + } + } + private static global::System.Attribute[] __Attributes_0(int groupIndex) + { + return new global::System.Attribute[] + { + new global::TUnit.Core.TestAttribute(), + new global::TUnit.Core.InheritsTestsAttribute() + }; + } + public static readonly global::TUnit.Core.TestEntry[] Entries_0 = new global::TUnit.Core.TestEntry[] + { + global::TUnit.Core.TestEntryFactory.Create( + methodName: "InheritedTest", + fullyQualifiedName: "TUnit.TestProject.Bugs._6657.CovariantPropertyOverrideTests.InheritedTest", + filePath: "", + lineNumber: 12, + methodMetadata: __mm_0, + createInstance: __CreateInstance_0, + invokeBody: __Invoke_0, + methodIndex: 0, + createAttributes: __Attributes_0, + attributeGroupIndex: 0), + }; +} +internal static partial class TUnit_TestRegistration +{ + static readonly int _r_TUnit_TestProject_Bugs__6657_CovariantPropertyOverrideTests_InheritedTest_TestSource_0 = global::TUnit.Core.SourceRegistrar.RegisterEntries(static () => TUnit_TestProject_Bugs__6657_CovariantPropertyOverrideTests_InheritedTest_TestSource.Entries_0); +} diff --git a/tests/TUnit.TestProject/Bugs/6657/Tests.cs b/tests/TUnit.TestProject/Bugs/6657/Tests.cs new file mode 100644 index 00000000000..95f95e052f6 --- /dev/null +++ b/tests/TUnit.TestProject/Bugs/6657/Tests.cs @@ -0,0 +1,22 @@ +namespace TUnit.TestProject.Bugs._6657; + +public interface IThing; + +public sealed class Thing : IThing; + +public abstract class BaseTests +{ + public abstract IThing Thing { get; } + + [Test] + public async Task InheritedTest() + { + await Assert.That(Thing).IsTypeOf(); + } +} + +[InheritsTests] +public sealed class CovariantPropertyOverrideTests : BaseTests +{ + public override Thing Thing { get; } = new(); +} From 3713bb6b49b9a3f15c6de6f07a136e789f400ad6 Mon Sep 17 00:00:00 2001 From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com> Date: Sun, 23 Aug 2026 16:53:37 +0100 Subject: [PATCH 2/2] fix(pack): stamp beta suffix in project, not pack command Passing -p:PackageVersion=x-beta flowed the suffix into the referenced TUnit.Assertions project, so TUnit.Assertions.Should shipped a dependency on "TUnit.Assertions >= x-beta" - a version never published. On prerelease builds that requirement outranks plain "x", so the doc-snippet consumer restore failed with NU1605 package downgrade. Stamp -beta inside TUnit.Assertions.Should.csproj (TreatAsLocalProperty) so only that package's own version carries it. Claude-Session: https://claude.ai/code/session_018ByiA1PmHUUxMptYhZfzRz --- .../TUnit.Assertions.Should.csproj | 13 ++++++++++++- .../TUnit.Pipeline/Modules/PackTUnitFilesModule.cs | 12 +++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/TUnit.Assertions.Should/TUnit.Assertions.Should.csproj b/src/TUnit.Assertions.Should/TUnit.Assertions.Should.csproj index f9ea4356314..cd4fb579207 100644 --- a/src/TUnit.Assertions.Should/TUnit.Assertions.Should.csproj +++ b/src/TUnit.Assertions.Should/TUnit.Assertions.Should.csproj @@ -1,8 +1,19 @@ - + + + + $(PackageVersion)-beta + $(Version)-beta + + diff --git a/tools/TUnit.Pipeline/Modules/PackTUnitFilesModule.cs b/tools/TUnit.Pipeline/Modules/PackTUnitFilesModule.cs index 82239d51798..feb015efad4 100644 --- a/tools/TUnit.Pipeline/Modules/PackTUnitFilesModule.cs +++ b/tools/TUnit.Pipeline/Modules/PackTUnitFilesModule.cs @@ -18,8 +18,11 @@ namespace TUnit.Pipeline.Modules; [DependsOn] public class PackTUnitFilesModule : Module> { - // Packages in beta get a "-beta" suffix appended to their version. - // Remove entries from this set once a package is considered stable. + // Packages in beta ship with a "-beta" suffix appended to their version. The suffix is + // stamped by the project file itself (see TUnit.Assertions.Should.csproj) so it never + // leaks into the versions of the sibling packages it depends on; this set only records + // the resulting package version. Keep it in sync with those project files, and remove + // entries once a package is considered stable. private static readonly HashSet BetaPackages = [ "TUnit.Assertions.Should" @@ -38,14 +41,13 @@ public class PackTUnitFilesModule : Module> foreach (var project in projects.ValueOrDefault!) { var projectName = project.NameWithoutExtension; - var isBeta = BetaPackages.Contains(projectName); - var packageVersion = isBeta + var packageVersion = BetaPackages.Contains(projectName) ? $"{version.SemVer!}-beta" : version.SemVer!; var properties = new List { - new KeyValue("PackageVersion", packageVersion), + new KeyValue("PackageVersion", version.SemVer!), new KeyValue("AssemblyVersion", version.AssemblySemVer!), new KeyValue("FileVersion", version.AssemblySemFileVer!), new KeyValue("InformationalVersion", version.InformationalVersion!),