Skip to content

Commit db1e3c2

Browse files
committed
Use runtime-specific assertions for Mono compatibility
1 parent f177877 commit db1e3c2

File tree

1 file changed

+41
-26
lines changed

1 file changed

+41
-26
lines changed

src/Shared/test/Shared.Tests/StackTraceHelperTest.cs

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace Microsoft.Extensions.Internal;
1515

1616
public class StackTraceHelperTest
1717
{
18+
private static bool IsMono => Type.GetType("Mono.RuntimeStructs") != null;
1819
[Fact]
1920
public void StackTraceHelper_IncludesLineNumbersForFiles()
2021
{
@@ -176,27 +177,33 @@ public void StackTraceHelper_ProducesReadableOutput()
176177

177178
// Act
178179
var stackFrames = StackTraceHelper.GetFrames(exception, out _);
179-
var methodNames = stackFrames.Select(stackFrame => stackFrame.MethodDisplayInfo.ToString()).ToList();
180-
181-
// Assert - Runtime-agnostic checks for essential stack trace components
182-
// Instead of exact string matching, verify key components are present
183-
Assert.Equal(expectedCallStack.Count, methodNames.Count);
184-
185-
// Check each frame contains the essential method information
186-
Assert.Contains("Iterator()+MoveNext()", methodNames[0]);
187-
Assert.Contains("string.Join", methodNames[1]);
188-
Assert.Contains("GenericClass<T>.GenericMethod<V>", methodNames[2]);
189-
Assert.Contains("MethodAsync(int value)", methodNames[3]);
190-
191-
// For async generic method, check for either resolved form or state machine form
192-
var asyncGenericFrame = methodNames[4];
193-
Assert.True(
194-
asyncGenericFrame.Contains("MethodAsync<TValue>(TValue value)") || // CoreCLR resolved form
195-
asyncGenericFrame.Contains("MethodAsync") && asyncGenericFrame.Contains("TValue"), // Mono state machine form
196-
$"Expected async generic method info in: {asyncGenericFrame}");
197-
198-
Assert.Contains("Method(string value)", methodNames[5]);
199-
Assert.Contains("StackTraceHelper_ProducesReadableOutput()", methodNames[6]);
180+
var methodNames = stackFrames.Select(stackFrame => stackFrame.MethodDisplayInfo.ToString()).ToArray();
181+
182+
// Assert
183+
Assert.Equal(expectedCallStack.Count, methodNames.Length);
184+
185+
if (IsMono)
186+
{
187+
// On Mono, verify key components are present but allow for runtime-specific formatting
188+
Assert.Contains("Iterator()+MoveNext()", methodNames[0]);
189+
Assert.Contains("string.Join", methodNames[1]);
190+
Assert.Contains("GenericClass<T>.GenericMethod<V>", methodNames[2]);
191+
Assert.Contains("MethodAsync(int value)", methodNames[3]);
192+
193+
// For async generic method on Mono, check for either resolved form or state machine form
194+
var asyncGenericFrame = methodNames[4];
195+
Assert.True(
196+
asyncGenericFrame.Contains("MethodAsync<TValue>(TValue value)") || // Resolved form
197+
asyncGenericFrame.Contains("MethodAsync") && asyncGenericFrame.Contains("TValue"), // State machine form
198+
$"Expected async generic method info in: {asyncGenericFrame}");
199+
200+
Assert.Contains("Method(string value)", methodNames[5]);
201+
Assert.Contains("StackTraceHelper_ProducesReadableOutput()", methodNames[6]);
202+
}
203+
else
204+
{
205+
Assert.Equal(expectedCallStack, methodNames);
206+
}
200207
}
201208

202209
[Fact]
@@ -259,12 +266,20 @@ public void GetFrames_DoesNotFailForDynamicallyGeneratedAssemblies()
259266
// Assert
260267
var frame = frames[0];
261268
Assert.Null(frame.FilePath);
262-
// Runtime-agnostic test: should contain "lambda_method" regardless of prefix
263-
// CoreCLR: "lambda_method34(Closure )"
264-
// Mono: "object.lambda_method34(Closure )"
265269
var methodDisplay = frame.MethodDisplayInfo.ToString();
266-
Assert.Contains("lambda_method", methodDisplay);
267-
Assert.EndsWith("(Closure )", methodDisplay);
270+
271+
if (IsMono)
272+
{
273+
// On Mono, lambda methods may include declaring type prefix (e.g., "object.lambda_method34")
274+
Assert.Contains("lambda_method", methodDisplay);
275+
Assert.EndsWith("(Closure )", methodDisplay);
276+
}
277+
else
278+
{
279+
// On CoreCLR, maintain strict check to prevent regressions
280+
Assert.StartsWith("lambda_method", methodDisplay);
281+
Assert.EndsWith("(Closure )", methodDisplay);
282+
}
268283
}
269284

270285
[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]

0 commit comments

Comments
 (0)