Skip to content

Commit 2f5676a

Browse files
committed
feat(nunit): add test fixture args to fullNames
1 parent 82cd902 commit 2f5676a

File tree

1 file changed

+80
-11
lines changed

1 file changed

+80
-11
lines changed

Allure.NUnit/Core/AllureNUnitHelper.cs

Lines changed: 80 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Globalization;
34
using System.Linq;
45
using System.Text;
56
using Allure.Net.Commons;
@@ -18,6 +19,14 @@ namespace Allure.NUnit.Core
1819
{
1920
sealed class AllureNUnitHelper
2021
{
22+
static Dictionary<Type, string> LiteralSuffixes { get; } = new()
23+
{
24+
{ typeof(uint), "u" },
25+
{ typeof(long), "L" },
26+
{ typeof(ulong), "UL" },
27+
{ typeof(float), "f" },
28+
};
29+
2130
private readonly ITest _test;
2231

2332
internal AllureNUnitHelper(ITest test)
@@ -96,7 +105,7 @@ internal static TestResult CreateTestResult(ITest test)
96105
var testResult = new TestResult
97106
{
98107
name = ResolveDisplayName(test),
99-
titlePath = EnumerateNamesFromTestFixtureToRoot(test).Reverse().ToList(),
108+
titlePath = [.. EnumerateTitlePathElements(test)],
100109
labels = [
101110
Label.Thread(),
102111
Label.Host(),
@@ -142,16 +151,23 @@ static string ResolveDisplayName(ITest test) =>
142151
_ => test.Name,
143152
};
144153

145-
static IEnumerable<string> EnumerateNamesFromTestFixtureToRoot(ITest test)
154+
static IEnumerable<ITest> EnumerateTestElements(ITest test)
146155
{
147-
for (ITest suite = GetTestFixture(test); suite is not null; suite = suite.Parent)
148-
yield return suite switch
149-
{
150-
TestAssembly a => a.Assembly?.GetName()?.Name ?? a.Name,
151-
_ => suite.Name,
152-
};
156+
Stack<ITest> stack = [];
157+
for (; test is not null; test = test.Parent)
158+
{
159+
stack.Push(test);
160+
}
161+
return stack;
153162
}
154163

164+
static IEnumerable<string> EnumerateTitlePathElements(ITest test) =>
165+
EnumerateTestElements(test).Skip(1).Select(suite => suite switch
166+
{
167+
TestAssembly a => a.Assembly?.GetName()?.Name ?? a.Name,
168+
_ => suite.Name,
169+
});
170+
155171
TestResultContainer CreateTestContainer() =>
156172
new()
157173
{
@@ -175,9 +191,62 @@ static void SetIdentifiers(ITest test, TestResult testResult)
175191
}
176192

177193
testResult.uuid = IdFunctions.CreateUUID();
178-
testResult.fullName = IdFunctions.CreateFullName(
179-
test.Method.MethodInfo
180-
);
194+
testResult.fullName = CreateFullName(test);
195+
}
196+
197+
/// <summary>
198+
/// For test fixtures with no parameters, returns the same value as
199+
/// <see cref="IdFunctions.CreateFullName(System.Reflection.MethodInfo)"/>.
200+
/// For test fixtures with parameters, inserts the arguments between the class and method IDs.
201+
/// </summary>
202+
static string CreateFullName(ITest test)
203+
{
204+
var testMethod = test.Method.MethodInfo;
205+
var testFixtureClass = testMethod.DeclaringType;
206+
var testFixtureArgs = GetTestFixture(test).Arguments;
207+
208+
var testFixtureClassPart = IdFunctions.GetTypeId(testFixtureClass);
209+
var testFixtureArgsPart = testFixtureArgs.Any()
210+
? $"({string.Join(",", testFixtureArgs.Select(FormatTestFixtureArg))})"
211+
: "";
212+
var methodPart = IdFunctions.GetMethodId(testMethod);
213+
214+
215+
return $"{testFixtureClassPart}{testFixtureArgsPart}.{methodPart}";
216+
}
217+
218+
/// <summary>
219+
/// Converts a test fixture argument to a string. Doesn't depend on the
220+
/// currently installed locale.
221+
/// </summary>
222+
/// <remarks>
223+
/// For possible values and types, see <see href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/attributes#2324-attribute-parameter-types">here</see>.
224+
/// </remarks>
225+
static string FormatTestFixtureArg(object value) => value switch
226+
{
227+
null => "null",
228+
string text => FormatFunctions.Format(text),
229+
Type type => $"<{IdFunctions.GetTypeId(type)}>",
230+
Array array => FormatArray(array),
231+
char c => FormatChar(c),
232+
_ => FormatPrimitive(value),
233+
};
234+
235+
static string FormatArray(Array array) =>
236+
$"[{string.Join(",", array.Cast<object>().Select(FormatTestFixtureArg))}]";
237+
238+
static string FormatChar(char c)
239+
{
240+
var text = FormatFunctions.Format(c);
241+
return $"'{text.Substring(1, text.Length - 2)}'";
242+
}
243+
244+
static string FormatPrimitive(object value)
245+
{
246+
var text = Convert.ToString(value, CultureInfo.InvariantCulture);
247+
return LiteralSuffixes.TryGetValue(value.GetType(), out var suffix)
248+
? $"{text}{suffix}"
249+
: text;
181250
}
182251

183252
static void SetLegacyIdentifiers(ITest test, TestResult testResult)

0 commit comments

Comments
 (0)