diff --git a/TUnit.Core.SourceGenerator.Tests/GenericMethodTests.Test.verified.txt b/TUnit.Core.SourceGenerator.Tests/GenericMethodTests.Test.verified.txt index d83b74209e..6cd74eaf06 100644 --- a/TUnit.Core.SourceGenerator.Tests/GenericMethodTests.Test.verified.txt +++ b/TUnit.Core.SourceGenerator.Tests/GenericMethodTests.Test.verified.txt @@ -1,11 +1,11 @@ -// +// #pragma warning disable #nullable enable namespace TUnit.Generated; [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute] [global::System.CodeDom.Compiler.GeneratedCode("TUnit", "1.0.0.0")] -internal sealed class TUnit_TestProject_GenericMethodTests_AggregateBy_HasExpectedOutput__IEnumerable_TSource__Func_TSource__TKey__Func_TKey__TAccumulate__Func_TAccumulate__TSource__TAccumulate__IEqualityComparer_TKey___IEnumerable_KeyValuePair_TKey__TAccumulate___TestSource : global::TUnit.Core.Interfaces.SourceGenerator.ITestSource, global::TUnit.Core.Interfaces.SourceGenerator.ITestDescriptorSource +internal sealed class TUnit_TestProject_GenericMethodTests_AggregateBy_HasExpectedOutput__IEnumerable_TSource__Func_TSource__TKey__Func_TKey__TAccumulate__Func_TAccumulate__TSource__TAccumulate__IEqualityComp_06BD488B_TestSource : global::TUnit.Core.Interfaces.SourceGenerator.ITestSource, global::TUnit.Core.Interfaces.SourceGenerator.ITestDescriptorSource { public async global::System.Collections.Generic.IAsyncEnumerable GetTestsAsync(string testSessionId, [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) { @@ -440,11 +440,11 @@ internal sealed class TUnit_TestProject_GenericMethodTests_AggregateBy_HasExpect }; } } -internal static class TUnit_TestProject_GenericMethodTests_AggregateBy_HasExpectedOutput__IEnumerable_TSource__Func_TSource__TKey__Func_TKey__TAccumulate__Func_TAccumulate__TSource__TAccumulate__IEqualityComparer_TKey___IEnumerable_KeyValuePair_TKey__TAccumulate___ModuleInitializer +internal static class TUnit_TestProject_GenericMethodTests_AggregateBy_HasExpectedOutput__IEnumerable_TSource__Func_TSource__TKey__Func_TKey__TAccumulate__Func_TAccumulate__TSource__TAccumulate__IEqualityComp_06BD488B_ModuleInitializer { [global::System.Runtime.CompilerServices.ModuleInitializer] public static void Initialize() { - global::TUnit.Core.SourceRegistrar.Register(typeof(global::TUnit.TestProject.GenericMethodTests), new TUnit_TestProject_GenericMethodTests_AggregateBy_HasExpectedOutput__IEnumerable_TSource__Func_TSource__TKey__Func_TKey__TAccumulate__Func_TAccumulate__TSource__TAccumulate__IEqualityComparer_TKey___IEnumerable_KeyValuePair_TKey__TAccumulate___TestSource()); + global::TUnit.Core.SourceRegistrar.Register(typeof(global::TUnit.TestProject.GenericMethodTests), new TUnit_TestProject_GenericMethodTests_AggregateBy_HasExpectedOutput__IEnumerable_TSource__Func_TSource__TKey__Func_TKey__TAccumulate__Func_TAccumulate__TSource__TAccumulate__IEqualityComp_06BD488B_TestSource()); } } diff --git a/TUnit.Core.SourceGenerator/Helpers/FileNameHelper.cs b/TUnit.Core.SourceGenerator/Helpers/FileNameHelper.cs index 5bcdfaf7ec..ff619469fd 100644 --- a/TUnit.Core.SourceGenerator/Helpers/FileNameHelper.cs +++ b/TUnit.Core.SourceGenerator/Helpers/FileNameHelper.cs @@ -15,6 +15,10 @@ internal static class FileNameHelper /// The type symbol for the test class /// The method symbol for the test method /// A deterministic filename like "MyNamespace_MyClass_MyMethod__Int32_String.g.cs" + // Conservative limit to avoid PathTooLongException on Windows with net472, + // which enforces the legacy 260-character MAX_PATH limit in Roslyn's AddSource. + private const int MaxHintNameLength = 200; + public static string GetDeterministicFileNameForMethod(INamedTypeSymbol typeSymbol, IMethodSymbol methodSymbol) { var sb = new StringBuilder(); @@ -71,8 +75,36 @@ public static string GetDeterministicFileNameForMethod(INamedTypeSymbol typeSymb } } - sb.Append(".g.cs"); - return sb.ToString(); + var baseName = sb.ToString(); + + // Truncate and append a hash if the name would exceed the limit + const int suffixLength = 5; // ".g.cs" + if (baseName.Length + suffixLength > MaxHintNameLength) + { + var hashSuffix = $"_{GetStableHashCode(baseName):X8}"; + var maxBaseLength = MaxHintNameLength - suffixLength - hashSuffix.Length; + baseName = baseName.Substring(0, maxBaseLength) + hashSuffix; + } + + return baseName + ".g.cs"; + } + + /// + /// Computes a deterministic hash code for a string (FNV-1a). + /// Unlike string.GetHashCode(), this is stable across processes and platforms. + /// + private static uint GetStableHashCode(string str) + { + unchecked + { + uint hash = 2166136261; + foreach (var c in str) + { + hash ^= c; + hash *= 16777619; + } + return hash; + } } ///