diff --git a/docs/mdsource/ignore-class-arguments.include.md b/docs/mdsource/ignore-class-arguments.include.md new file mode 100644 index 000000000..b22488a03 --- /dev/null +++ b/docs/mdsource/ignore-class-arguments.include.md @@ -0,0 +1,17 @@ +### Ignore class arguments + +`VerifierSettings.IgnoreClassArguments()` can be used to globally ignore class constructor arguments from the verified filename. This is useful when infrastructure fixtures (e.g. TUnit's `ClassConstructor` or NUnit's `TestFixtureSource`) are injected via the constructor and should not affect snapshot file names. It must be called before any test runs, typically in a `[ModuleInitializer]`. + +The received files still contain all class argument values. + +```cs +[ModuleInitializer] +public static void Init() => + VerifierSettings.IgnoreClassArguments(); +``` + +`IgnoreClassArguments` can also be used at the test level: + +```cs +await Verify(result).IgnoreClassArguments(); +``` diff --git a/docs/mdsource/parameterised-nunit.source.md b/docs/mdsource/parameterised-nunit.source.md index d1fbf4227..2f95ed7d5 100644 --- a/docs/mdsource/parameterised-nunit.source.md +++ b/docs/mdsource/parameterised-nunit.source.md @@ -68,6 +68,11 @@ snippet: IgnoreParametersForVerifiedNunit snippet: IgnoreParametersForVerifiedFluentNunit +## Ignore class arguments for verified filename + +include: ignore-class-arguments + + ## IgnoreParametersForVerified with override parameters The parameters passed to IgnoreParametersForVerified can be used pass custom parameters to [UseParameters](#UseParameters). diff --git a/docs/mdsource/parameterised-tunit.source.md b/docs/mdsource/parameterised-tunit.source.md index ebbf3687f..b509de531 100644 --- a/docs/mdsource/parameterised-tunit.source.md +++ b/docs/mdsource/parameterised-tunit.source.md @@ -56,6 +56,11 @@ snippet: IgnoreParametersForVerifiedTUnit snippet: IgnoreParametersForVerifiedFluentTUnit +## Ignore class arguments for verified filename + +include: ignore-class-arguments + + ## IgnoreParametersForVerified with override parameters The parameters passed to IgnoreParametersForVerified can be used pass custom parameters to [UseParameters](#UseParameters). diff --git a/docs/parameterised-nunit.md b/docs/parameterised-nunit.md index b5e76c003..20b4304c8 100644 --- a/docs/parameterised-nunit.md +++ b/docs/parameterised-nunit.md @@ -250,6 +250,28 @@ public Task IgnoreParametersForVerifiedFluent(string arg) => +## Ignore class arguments for verified filename + +### Ignore class arguments + +`VerifierSettings.IgnoreClassArguments()` can be used to globally ignore class constructor arguments from the verified filename. This is useful when infrastructure fixtures (e.g. TUnit's `ClassConstructor` or NUnit's `TestFixtureSource`) are injected via the constructor and should not affect snapshot file names. It must be called before any test runs, typically in a `[ModuleInitializer]`. + +The received files still contain all class argument values. + +```cs +[ModuleInitializer] +public static void Init() => + VerifierSettings.IgnoreClassArguments(); +``` + +`IgnoreClassArguments` can also be used at the test level: + +```cs +await Verify(result).IgnoreClassArguments(); +``` + + + ## IgnoreParametersForVerified with override parameters The parameters passed to IgnoreParametersForVerified can be used pass custom parameters to [UseParameters](#UseParameters). diff --git a/docs/parameterised-tunit.md b/docs/parameterised-tunit.md index 72d3df741..45e911de4 100644 --- a/docs/parameterised-tunit.md +++ b/docs/parameterised-tunit.md @@ -197,6 +197,28 @@ public Task IgnoreParametersForVerifiedFluent(string arg) => +## Ignore class arguments for verified filename + +### Ignore class arguments + +`VerifierSettings.IgnoreClassArguments()` can be used to globally ignore class constructor arguments from the verified filename. This is useful when infrastructure fixtures (e.g. TUnit's `ClassConstructor` or NUnit's `TestFixtureSource`) are injected via the constructor and should not affect snapshot file names. It must be called before any test runs, typically in a `[ModuleInitializer]`. + +The received files still contain all class argument values. + +```cs +[ModuleInitializer] +public static void Init() => + VerifierSettings.IgnoreClassArguments(); +``` + +`IgnoreClassArguments` can also be used at the test level: + +```cs +await Verify(result).IgnoreClassArguments(); +``` + + + ## IgnoreParametersForVerified with override parameters The parameters passed to IgnoreParametersForVerified can be used pass custom parameters to [UseParameters](#UseParameters). diff --git a/src/StaticSettingsTests/IgnoreClassArgumentsTests.IgnoreClassArguments.verified.txt b/src/StaticSettingsTests/IgnoreClassArgumentsTests.IgnoreClassArguments.verified.txt new file mode 100644 index 000000000..2890eead2 --- /dev/null +++ b/src/StaticSettingsTests/IgnoreClassArgumentsTests.IgnoreClassArguments.verified.txt @@ -0,0 +1 @@ +value \ No newline at end of file diff --git a/src/StaticSettingsTests/IgnoreClassArgumentsTests.cs b/src/StaticSettingsTests/IgnoreClassArgumentsTests.cs new file mode 100644 index 000000000..a17de11b8 --- /dev/null +++ b/src/StaticSettingsTests/IgnoreClassArgumentsTests.cs @@ -0,0 +1,17 @@ +public class IgnoreClassArgumentsTests : + BaseTest +{ + public IgnoreClassArgumentsTests() => + VerifierSettings.IgnoreClassArguments(); + + [Theory] + [InlineData("One")] + [InlineData("Two")] + public Task IgnoreClassArguments(string classArg) + { + var settings = new VerifySettings(); + settings.UseParameters(classArg); + settings.SetClassArgumentCount(1); + return Verify("value", settings); + } +} diff --git a/src/Verify.NUnit/Verifier.cs b/src/Verify.NUnit/Verifier.cs index 9b15934d8..4d2859118 100644 --- a/src/Verify.NUnit/Verifier.cs +++ b/src/Verify.NUnit/Verifier.cs @@ -36,8 +36,9 @@ public static InnerVerifier BuildVerifier(string sourceFile, VerifySettings sett } else { - (parameterNames, var parameters) = GetParametersAndNames(method, adapter); + (parameterNames, var parameters, var classArgumentCount) = GetParametersAndNames(method, adapter); settings.SetParameters(parameters); + settings.SetClassArgumentCount(classArgumentCount); } VerifierSettings.AssignTargetAssembly(type.Assembly); @@ -58,29 +59,30 @@ public static InnerVerifier BuildVerifier(string sourceFile, VerifySettings sett return adapter.GetParameterNames(methodParameterNames); } - static (IReadOnlyList? names, object?[] parameters) GetParametersAndNames(MethodInfo method, TestAdapter adapter) + static (IReadOnlyList? names, object?[] parameters, int classArgumentCount) GetParametersAndNames(MethodInfo method, TestAdapter adapter) { var methodParameterNames = method.ParameterNames(); var parameterNames = adapter.GetParameterNames(methodParameterNames); if (!adapter.TryGetParent(out var parent)) { - return (parameterNames, adapter.Arguments); + return (parameterNames, adapter.Arguments, 0); } var argumentsLength = parent.Arguments.Length; if (argumentsLength == 0) { - return (parameterNames, adapter.Arguments); + return (parameterNames, adapter.Arguments, 0); } if (methodParameterNames == null) { - return (parameterNames, parent.Arguments); + return (parameterNames, parent.Arguments, argumentsLength); } return ( parameterNames, - [.. parent.Arguments, .. adapter.Arguments]); + [.. parent.Arguments, .. adapter.Arguments], + argumentsLength); } static SettingsTask Verify( diff --git a/src/Verify.TUnit/Verifier.cs b/src/Verify.TUnit/Verifier.cs index d7466bf06..1934d66a4 100644 --- a/src/Verify.TUnit/Verifier.cs +++ b/src/Verify.TUnit/Verifier.cs @@ -37,6 +37,7 @@ public static InnerVerifier BuildVerifier(string sourceFile, VerifySettings sett methodArguments.Length > 0)) { settings.SetParameters([.. classArguments, .. methodArguments]); + settings.SetClassArgumentCount(classArguments.Length); } VerifierSettings.AssignTargetAssembly(type.Assembly); diff --git a/src/Verify/Naming/FileNameBuilder.cs b/src/Verify/Naming/FileNameBuilder.cs index 889295ea9..e33388c19 100644 --- a/src/Verify/Naming/FileNameBuilder.cs +++ b/src/Verify/Naming/FileNameBuilder.cs @@ -67,6 +67,23 @@ public static (Action?, Action?) GetParameterText( } } + if (settings.ignoreClassArguments || VerifierSettings.GlobalIgnoreClassArguments) + { + var classArgCount = settings.classArgumentCount; + if (classArgCount > 0) + { + var classParamNames = methodParameters.Take(classArgCount); + if (ignored is not null) + { + ignored = [..ignored, ..classParamNames]; + } + else + { + ignored = classParamNames.ToHashSet(); + } + } + } + var verifiedValues = GetVerifiedValues(ignored, allValues); if (settings.ParametersAppender == null) diff --git a/src/Verify/Naming/VerifierSettings.cs b/src/Verify/Naming/VerifierSettings.cs index 83183850c..bee97fe82 100644 --- a/src/Verify/Naming/VerifierSettings.cs +++ b/src/Verify/Naming/VerifierSettings.cs @@ -361,4 +361,16 @@ public static void IgnoreParameters(params string[] parameterNames) InnerVerifier.ThrowIfVerifyHasBeenRun(); GlobalIgnoredParameters = parameterNames.ToHashSet(); } + + internal static bool GlobalIgnoreClassArguments; + + /// + /// Ignore class arguments in 'verified' filename resulting in the same verified file regardless of class constructor arguments. + /// Note that the 'received' files still contain the class arguments. + /// + public static void IgnoreClassArguments() + { + InnerVerifier.ThrowIfVerifyHasBeenRun(); + GlobalIgnoreClassArguments = true; + } } \ No newline at end of file diff --git a/src/Verify/Naming/VerifySettings_Parameter.cs b/src/Verify/Naming/VerifySettings_Parameter.cs index ae30dd078..f7fefd105 100644 --- a/src/Verify/Naming/VerifySettings_Parameter.cs +++ b/src/Verify/Naming/VerifySettings_Parameter.cs @@ -82,6 +82,20 @@ void ThrowIfParametersTextDefined([CallerMemberName] string caller = "") public void IgnoreParameters(params string[] parameterNames) => ignoredParameters = parameterNames.ToHashSet(); + internal int classArgumentCount; + + internal void SetClassArgumentCount(int count) => + classArgumentCount = count; + + internal bool ignoreClassArguments; + + /// + /// Ignore class arguments in 'verified' filename resulting in the same verified file regardless of class constructor arguments. + /// Note that the 'received' files still contain the class arguments. + /// + public void IgnoreClassArguments() => + ignoreClassArguments = true; + internal bool ignoreParametersForVerified; /// diff --git a/src/Verify/Serialization/VerifierSettings.cs b/src/Verify/Serialization/VerifierSettings.cs index c448df3c5..4d1bb8671 100644 --- a/src/Verify/Serialization/VerifierSettings.cs +++ b/src/Verify/Serialization/VerifierSettings.cs @@ -167,6 +167,7 @@ internal static void Reset() addAttachments = true; GlobalScrubbers.Clear(); GlobalIgnoredParameters = null; + GlobalIgnoreClassArguments = false; } public static void UseStrictJson() diff --git a/src/Verify/SettingsTask_Parameters.cs b/src/Verify/SettingsTask_Parameters.cs index fa17453ab..d8922e2d4 100644 --- a/src/Verify/SettingsTask_Parameters.cs +++ b/src/Verify/SettingsTask_Parameters.cs @@ -10,6 +10,14 @@ public SettingsTask IgnoreParameters(params string[] parameterNames) return this; } + /// + [Pure] + public SettingsTask IgnoreClassArguments() + { + CurrentSettings.IgnoreClassArguments(); + return this; + } + /// [Pure] public SettingsTask IgnoreParametersForVerified(params object?[] parameters) diff --git a/src/Verify/VerifySettings.cs b/src/Verify/VerifySettings.cs index 9acf00413..e474d955e 100644 --- a/src/Verify/VerifySettings.cs +++ b/src/Verify/VerifySettings.cs @@ -49,6 +49,8 @@ public VerifySettings(VerifySettings? settings) extensionStreamComparers = settings.extensionStreamComparers; parameters = settings.parameters; ignoredParameters = settings.ignoredParameters; + classArgumentCount = settings.classArgumentCount; + ignoreClassArguments = settings.ignoreClassArguments; ignoreParametersForVerified = settings.ignoreParametersForVerified; parametersText = settings.parametersText; FileName = settings.FileName;