Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breaking: Respect NUnit class level parameters and drop support for custom TestName #1249

Merged
merged 28 commits into from
Jul 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d16c095
use named class level parameters
SimonCropp Jul 16, 2024
f4e7475
Merge branch 'main' into use-named-class-level-parameters
SimonCropp Jul 17, 2024
6e06277
Update Verifier.cs
SimonCropp Jul 17, 2024
fbbbb6e
Update GlobalUsings.cs
SimonCropp Jul 17, 2024
7dcbb59
Merge branch 'main' into use-named-class-level-parameters
SimonCropp Jul 17, 2024
17ac809
Update Verifier.cs
SimonCropp Jul 17, 2024
f7ee4d1
.
SimonCropp Jul 17, 2024
9ec21fa
.
SimonCropp Jul 17, 2024
2d2b833
Update Verifier.cs
SimonCropp Jul 17, 2024
d246b36
.
SimonCropp Jul 17, 2024
b933683
Update TestFixtureSourceUsage.Test_arg1=Value2_arg2=2.verified.txt
SimonCropp Jul 17, 2024
ede8f1c
Update ClassLevelParams.cs
SimonCropp Jul 17, 2024
51a036a
Create ClassLevelParams.Simple_arg1=2.verified.txt
SimonCropp Jul 17, 2024
d72d311
Update Extensions.cs
SimonCropp Jul 17, 2024
a7563b4
Update Verifier.cs
SimonCropp Jul 17, 2024
686619a
Merge branch 'main' into use-named-class-level-parameters
SimonCropp Jul 17, 2024
0fb8cff
.
SimonCropp Jul 17, 2024
b56ee15
Update Verifier.cs
SimonCropp Jul 17, 2024
1d9a11a
.
SimonCropp Jul 17, 2024
25649ae
Merge branch 'main' into use-named-class-level-parameters
SimonCropp Jul 17, 2024
a3f5a44
.
SimonCropp Jul 17, 2024
7fddf45
Merge branch 'main' into use-named-class-level-parameters
SimonCropp Jul 17, 2024
4c7efb0
Merge branch 'main' into use-named-class-level-parameters
SimonCropp Jul 19, 2024
f17e6c8
Update FileNameCleaner.cs
SimonCropp Jul 19, 2024
370f582
.
SimonCropp Jul 19, 2024
56c050e
Merge branch 'main' into use-named-class-level-parameters
SimonCropp Jul 19, 2024
632e70c
Merge branch 'main' into use-named-class-level-parameters
SimonCropp Jul 19, 2024
6188757
.
SimonCropp Jul 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion docs/mdsource/parameterised.source.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ When using a [TestFixtureSource](https://docs.nunit.org/articles/nunit/writing-t

snippet: TestFixtureSourceUsage.cs

Produces `TestFixtureSourceUsage(Value1,1).Test.verified.txt` and `TestFixtureSourceUsage(Value2,2).Test.verified.txt`.
Produces:

* `TestFixtureSourceUsage.Test_arg1=Value1_arg2=1.verified.txt`
* `TestFixtureSourceUsage.Test_arg1=Value2_arg2=2.verified.txt`


## xUnit
Expand Down
5 changes: 4 additions & 1 deletion docs/parameterised.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,10 @@ public class TestFixtureSourceUsage(string arg1, int arg2)
<sup><a href='/src/Verify.NUnit.Tests/TestFixtureSourceUsage.cs#L1-L26' title='Snippet source file'>snippet source</a> | <a href='#snippet-TestFixtureSourceUsage.cs' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

Produces `TestFixtureSourceUsage(Value1,1).Test.verified.txt` and `TestFixtureSourceUsage(Value2,2).Test.verified.txt`.
Produces:

* `TestFixtureSourceUsage.Test_arg1=Value1_arg2=1.verified.txt`
* `TestFixtureSourceUsage.Test_arg1=Value2_arg2=2.verified.txt`


## xUnit
Expand Down
10 changes: 0 additions & 10 deletions src/Benchmarks/FileNameCleanerBenchmarks.cs

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Value1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Value1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

2 changes: 2 additions & 0 deletions src/Verify.NUnit/GlobalUsings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
global using NUnit.Framework.Internal;
global using NUnit.Framework.Interfaces;
global using VerifyTests;

global using TestAdapter = NUnit.Framework.TestContext.TestAdapter;
127 changes: 97 additions & 30 deletions src/Verify.NUnit/Verifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,63 +31,130 @@ static InnerVerifier BuildVerifier(string sourceFile, VerifySettings settings, b
throw new("TestContext.CurrentContext.Test.Method is null. Verify can only be used from within a test method.");
}

if (!settings.HasParameters &&
adapter.Arguments.Length > 0)
var method = testMethod.MethodInfo;
var type = testMethod.TypeInfo.Type;

IReadOnlyList<string>? parameterNames;
if (settings.HasParameters)
{
settings.SetParameters(adapter.Arguments);
parameterNames = GetParameterNames(adapter);
}

var customName = !adapter.FullName.StartsWith($"{testMethod.TypeInfo.FullName}.{testMethod.Name}");
if (customName)
else
{

settings.typeName ??= adapter.GetTypeName();

settings.methodName ??= adapter.GetMethodName();
var (names, values) = GetParameterInfo(adapter);
settings.SetParameters(values);
parameterNames = names;
}

var type = testMethod.TypeInfo.Type;
VerifierSettings.AssignTargetAssembly(type.Assembly);

var method = testMethod.MethodInfo;

var pathInfo = GetPathInfo(sourceFile, type, method);
return new(
sourceFile,
settings,
type.NameWithParent(),
method.Name,
method.ParameterNames(),
parameterNames,
pathInfo);
}

static string GetMethodName(this TestContext.TestAdapter adapter)
static (IReadOnlyList<string>? names, object?[] values) GetParameterInfo(TestAdapter adapter)
{
var name = adapter.Name;
var indexOf = name.IndexOf('(');
var method = adapter.Method!;

if (indexOf != -1)
var methodParameterNames = method.MethodInfo.ParameterNames();

var parent = GetParent(adapter);

if (parent == null)
{
name = name[..indexOf];
return (methodParameterNames, adapter.Arguments);
}

return name.ReplaceInvalidFileNameChars();
var argumentsLength = parent.Arguments.Length;
if (argumentsLength == 0)
{
return (methodParameterNames, adapter.Arguments);
}

var names = GetConstructorParameterNames(method.TypeInfo.Type, argumentsLength);
if (methodParameterNames == null)
{
return (names.ToList(), parent.Arguments);
}

return (
[.. names, .. methodParameterNames],
[.. parent.Arguments, .. adapter.Arguments]);
}

static string GetTypeName(this TestContext.TestAdapter adapter)
static IReadOnlyList<string>? GetParameterNames(TestAdapter adapter)
{
var fullName = adapter.FullName.AsSpan();
var fullNameLength = fullName.Length - (adapter.Name.Length + 1);
var typeName = fullName[..fullNameLength];
var typeInfo = adapter.Method!.TypeInfo;
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
if (typeInfo.Namespace is not null)
var method = adapter.Method!;

var methodParameterNames = method.MethodInfo.ParameterNames();

var parent = GetParent(adapter);

if (parent == null)
{
return methodParameterNames;
}

var names = GetConstructorParameterNames(method.TypeInfo.Type, parent.Arguments.Length);
if (methodParameterNames == null)
{
return names.ToList();
}

return [.. names, .. methodParameterNames];
}

static ITest? GetParent(TestAdapter adapter)
{
var test = GetTest(adapter);
var parent = test.Parent;
if (parent is ParameterizedMethodSuite methodSuite)
{
return methodSuite.Parent;
}

return parent;
}

static Test GetTest(TestAdapter adapter)
{
var field = adapter
.GetType()
.GetField("_test", BindingFlags.Instance | BindingFlags.NonPublic)!;
return (Test) field.GetValue(adapter)!;
}

static IEnumerable<string> GetConstructorParameterNames(Type type, int argumentsLength)
{
IEnumerable<string>? names = null;
foreach (var constructor in type.GetConstructors(BindingFlags.Instance | BindingFlags.Public))
{
var parameters = constructor.GetParameters();
if (parameters.Length != argumentsLength)
{
continue;
}

if (names != null)
{
throw new($"Found multiple constructors with {argumentsLength} parameters. Unable to derive names of parameters. Instead use UseParameters to pass in explicit parameter.");
}

names = parameters.Select(_ => _.Name!);
}

if (names == null)
{
typeName = typeName[(typeInfo.Namespace.Length + 1)..];
throw new($"Could not find constructor with {argumentsLength} parameters.");
}

return typeName.ToString().Replace("\"", "")
.ReplaceInvalidFileNameChars();
return names;
}

static SettingsTask Verify(
Expand Down

This file was deleted.

6 changes: 0 additions & 6 deletions src/Verify.Tests/FileNameCleanerBenchmarksTests.cs

This file was deleted.

27 changes: 0 additions & 27 deletions src/Verify/FileNameCleaner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,33 +49,6 @@
static SearchValues<char> invalidFileNameSearchValues = SearchValues.Create(invalidFileNameChars);
#endif

public static string ReplaceInvalidFileNameChars(this string value)
{
var span = value.AsSpan();

var index = IndexOfInvalidChar(span);

if (index == -1)
{
return value;
}

Span<char> target = stackalloc char[value.Length];
span.CopyTo(target);

target[index] = '-';
index++;
for (; index < target.Length; index++)
{
if (IsInvalid(target[index]))
{
target[index] = '-';
}
}

return target.ToString();
}

static int IndexOfInvalidChar(CharSpan span) =>
#if NET8_0_OR_GREATER
span.IndexOfAny(invalidFileNameSearchValues);
Expand Down
Loading