diff --git a/docs/combinations.md b/docs/combinations.md index 41e384a0d..a04ea371c 100644 --- a/docs/combinations.md +++ b/docs/combinations.md @@ -210,7 +210,7 @@ public class CombinationResultsConverter : for (var keyIndex = 0; keyIndex < keysLength; keyIndex++) { var key = item.Keys[keyIndex]; - var name = VerifierSettings.GetNameForParameter(key, pathFriendly: false); + var name = VerifierSettings.GetNameForParameter(key, writer.Counter, pathFriendly: false); keyValues[itemIndex, keyIndex] = name; var currentKeyLength = maxKeyLengths[keyIndex]; if (name.Length > currentKeyLength) diff --git a/docs/naming.md b/docs/naming.md index 1acbcd576..695242243 100644 --- a/docs/naming.md +++ b/docs/naming.md @@ -32,7 +32,7 @@ var settings = new VerifySettings(); settings.UseDirectory("CustomDirectory"); await Verify("valueUseDirectory", settings); ``` -snippet source | anchor +snippet source | anchor @@ -44,7 +44,7 @@ await Verify("valueUseDirectory", settings); await Verify("valueUseDirectoryFluent") .UseDirectory("CustomDirectory"); ``` -snippet source | anchor +snippet source | anchor Will result in `CustomDirectory/TypeName.MethodName.verified.txt`. @@ -64,7 +64,7 @@ var settings = new VerifySettings(); settings.UseTypeName("CustomTypeName"); await Verify("valueUseTypeName", settings); ``` -snippet source | anchor +snippet source | anchor @@ -76,7 +76,7 @@ await Verify("valueUseTypeName", settings); await Verify("valueUseTypeNameFluent") .UseTypeName("CustomTypeName"); ``` -snippet source | anchor +snippet source | anchor Will result in `CustomTypeName.MethodName.verified.txt`. @@ -93,7 +93,7 @@ var settings = new VerifySettings(); settings.UseMethodName("CustomMethodName"); await Verify("valueUseMethodName", settings); ``` -snippet source | anchor +snippet source | anchor Will result in `TestClass.CustomMethodName.verified.txt`. @@ -107,7 +107,7 @@ Will result in `TestClass.CustomMethodName.verified.txt`. await Verify("valueUseMethodNameFluent") .UseMethodName("CustomMethodNameFluent"); ``` -snippet source | anchor +snippet source | anchor Will result in `TestClass.CustomMethodNameFluent.verified.txt`. @@ -160,7 +160,7 @@ Will result in `CustomFileName.verified.txt`. await Verify("valueUseFileNameFluent") .UseFileName("CustomFileNameFluent"); ``` -snippet source | anchor +snippet source | anchor Will result in `UseFileNameFluent.verified.txt`. @@ -660,7 +660,7 @@ To access the current Namer `Runtime` or `RuntimeAndVersion` strings use: Debug.WriteLine(Namer.Runtime); Debug.WriteLine(Namer.RuntimeAndVersion); ``` -snippet source | anchor +snippet source | anchor @@ -834,7 +834,7 @@ var settings = new VerifySettings(); settings.UseUniqueDirectory(); await Verify("TheValue", settings); ``` -snippet source | anchor +snippet source | anchor diff --git a/src/Verify.Tests/Naming/NameForParameterTests.cs b/src/Verify.Tests/Naming/NameForParameterTests.cs index 2c782dd8a..7ad37cb7f 100644 --- a/src/Verify.Tests/Naming/NameForParameterTests.cs +++ b/src/Verify.Tests/Naming/NameForParameterTests.cs @@ -2,62 +2,83 @@ { [Fact] public Task Null() => - Verify(VerifierSettings.GetNameForParameter(null)); + Verify(VerifierSettings.GetNameForParameter(null, counter: Counter())); [Fact] public Task StringEmpty() => - Verify(VerifierSettings.GetNameForParameter("")); + Verify(VerifierSettings.GetNameForParameter("", counter: Counter())); [Fact] public Task StringInvalidPathChar() => - Verify(VerifierSettings.GetNameForParameter("a/a")); + Verify(VerifierSettings.GetNameForParameter("a/a", counter: Counter())); [Fact] public Task Int() => - Verify(VerifierSettings.GetNameForParameter(10)); + Verify(VerifierSettings.GetNameForParameter(10, counter: Counter())); #if NET6_0_OR_GREATER [Fact] public Task Half() => - Verify(VerifierSettings.GetNameForParameter((Half) 10)); + Verify( + VerifierSettings.GetNameForParameter( + (Half) 10, + counter: Counter())); #endif #if NET6_0_OR_GREATER [Fact] public Task Date() => - Verify(VerifierSettings.GetNameForParameter(new Date(2000, 10, 1))); + Verify( + VerifierSettings.GetNameForParameter( + new Date(2000, 10, 1), + counter: Counter())); [Fact] public Task Time() => - Verify(VerifierSettings.GetNameForParameter(new Date(2000, 10, 1))); + Verify( + VerifierSettings.GetNameForParameter( + new Date(2000, 10, 1), + counter: Counter())); #endif [Fact] public Task DateTimeLocal() { var date = new DateTime(2000, 10, 1, 0, 0, 0, DateTimeKind.Local); - return Verify(VerifierSettings.GetNameForParameter(date)); + return Verify( + VerifierSettings.GetNameForParameter( + date, + counter: Counter())); } [Fact] public Task DateTimeUnspecified() { var date = new DateTime(2000, 10, 1, 0, 0, 0); - return Verify(VerifierSettings.GetNameForParameter(date)); + return Verify( + VerifierSettings.GetNameForParameter( + date, + counter: Counter())); } [Fact] public Task DateTimeUtc() { var date = new DateTime(2000, 10, 1, 0, 0, 0, DateTimeKind.Utc); - return Verify(VerifierSettings.GetNameForParameter(date)); + return Verify( + VerifierSettings.GetNameForParameter( + date, + counter: Counter())); } [Fact] public Task DateTimeOffsetUtc() { var date = new DateTimeOffset(2000, 10, 1, 0, 0, 0, TimeSpan.Zero); - return Verify(VerifierSettings.GetNameForParameter(date)); + return Verify( + VerifierSettings.GetNameForParameter( + date, + counter: Counter())); } [Fact] @@ -66,16 +87,19 @@ public Task List() => new List { "value" - })); + }, + counter: Counter())); [Fact] public Task ListMultiple() => - Verify(VerifierSettings.GetNameForParameter( + Verify( + VerifierSettings.GetNameForParameter( new List { "value1", "value2" - })); + }, + counter: Counter())); [Fact] public Task Nested() => @@ -93,11 +117,15 @@ public Task Nested() => } }, "value4" - })); + }, + counter: Counter())); [Fact] public Task EmptyList() => - Verify(VerifierSettings.GetNameForParameter(new List())); + Verify( + VerifierSettings.GetNameForParameter( + new List(), + counter: Counter())); [Fact] public Task Dictionary() => @@ -107,7 +135,8 @@ public Task Dictionary() => { "value", 10 } - })); + }, + counter: Counter())); [Fact] public Task DictionaryMultiple() => @@ -120,23 +149,43 @@ public Task DictionaryMultiple() => { "value2", 11 } - })); + }, + counter: Counter())); [Fact] public Task EmptyDictionary() => - Verify(VerifierSettings.GetNameForParameter(new Dictionary())); + Verify( + VerifierSettings.GetNameForParameter( + new Dictionary(), + counter: Counter())); [Fact] public Task EnumerableStaticEmpty() => - Verify(VerifierSettings.GetNameForParameter(Enumerable.Empty())); + Verify( + VerifierSettings.GetNameForParameter( + Enumerable.Empty(), + counter: Counter())); [Fact] public Task Array() => - Verify(VerifierSettings.GetNameForParameter( + Verify( + VerifierSettings.GetNameForParameter( new[] { "value" - })); + }, + counter: Counter())); + + private static Counter Counter() => + new( + true, +#if NET6_0_OR_GREATER + [], + [], +#endif + [], + [], + []); [Fact] public Task ArrayMultiple() => @@ -145,9 +194,13 @@ public Task ArrayMultiple() => { "value1", "value2" - })); + }, + counter: Counter())); [Fact] public Task ArrayEmpty() => - Verify(VerifierSettings.GetNameForParameter(System.Array.Empty())); + Verify( + VerifierSettings.GetNameForParameter( + System.Array.Empty(), + counter: Counter())); } \ No newline at end of file diff --git a/src/Verify.Tests/Naming/NamerTests.NamedGuid_guid=guidOne.verified.txt b/src/Verify.Tests/Naming/NamerTests.NamedGuid_guid=guidOne.verified.txt new file mode 100644 index 000000000..91e58a79d --- /dev/null +++ b/src/Verify.Tests/Naming/NamerTests.NamedGuid_guid=guidOne.verified.txt @@ -0,0 +1 @@ +Content \ No newline at end of file diff --git a/src/Verify.Tests/Naming/NamerTests.NamedGuid_guid=guidTwo.verified.txt b/src/Verify.Tests/Naming/NamerTests.NamedGuid_guid=guidTwo.verified.txt new file mode 100644 index 000000000..91e58a79d --- /dev/null +++ b/src/Verify.Tests/Naming/NamerTests.NamedGuid_guid=guidTwo.verified.txt @@ -0,0 +1 @@ +Content \ No newline at end of file diff --git a/src/Verify.Tests/Naming/NamerTests.cs b/src/Verify.Tests/Naming/NamerTests.cs index 0d4ff2f60..7739be2cb 100644 --- a/src/Verify.Tests/Naming/NamerTests.cs +++ b/src/Verify.Tests/Naming/NamerTests.cs @@ -185,9 +185,12 @@ public Task UseFileNameWithUnique() [Fact] public async Task UseFileNameFluent() => - #region UseFileNameFluent + + #region UseFileNameFluent + await Verify("valueUseFileNameFluent") .UseFileName("CustomFileNameFluent"); + #endregion [Fact] @@ -204,9 +207,12 @@ public async Task UseDirectory() [Fact] public async Task UseDirectoryFluent() => - #region UseDirectoryFluent + + #region UseDirectoryFluent + await Verify("valueUseDirectoryFluent") .UseDirectory("CustomDirectory"); + #endregion @@ -224,9 +230,12 @@ public async Task UseUniqueDirectory() [Fact] public async Task UseUniqueDirectoryFluent() => - #region UseUniqueDirectoryFluent + + #region UseUniqueDirectoryFluent + await Verify("TheValue") .UseUniqueDirectory(); + #endregion [Fact] @@ -298,9 +307,12 @@ public async Task UseTypeName() [Fact] public async Task UseTypeNameFluent() => - #region UseTypeNameFluent + + #region UseTypeNameFluent + await Verify("valueUseTypeNameFluent") .UseTypeName("CustomTypeName"); + #endregion [Fact] @@ -317,9 +329,12 @@ public async Task UseMethodName() [Fact] public async Task UseMethodNameFluent() => - #region UseMethodNameFluent + + #region UseMethodNameFluent + await Verify("valueUseMethodNameFluent") .UseMethodName("CustomMethodNameFluent"); + #endregion @@ -385,8 +400,11 @@ public Task UseTextForParametersNoParam() => [Fact] public void AccessNamerArchitecture() => - #region AccessNamerArchitecture + + #region AccessNamerArchitecture + Debug.WriteLine(Namer.Architecture); + #endregion [Fact] @@ -527,4 +545,18 @@ public Task HashParametersFluent(bool a, bool b) => Verify("ContentHashParametersFluent") .UseParameters(a, b) .HashParameters(); + + [ModuleInitializer] + public static void InitNamedParams() + { + VerifierSettings.AddNamedGuid(new Guid("58035867-560f-4c58-b394-ec4ea98e6be4"), "guidOne"); + VerifierSettings.AddNamedGuid(new Guid("e5128186-eb54-4b83-921d-8a6dc03141c1"), "guidTwo"); + } + + [Theory] + [InlineData("58035867-560f-4c58-b394-ec4ea98e6be4")] + [InlineData("e5128186-eb54-4b83-921d-8a6dc03141c1")] + public Task NamedGuid(Guid guid) => + Verify("Content") + .UseParameters(guid); } \ No newline at end of file diff --git a/src/Verify/Combinations/CombinationResultsConverter.cs b/src/Verify/Combinations/CombinationResultsConverter.cs index 3f52b572f..5df7c85e4 100644 --- a/src/Verify/Combinations/CombinationResultsConverter.cs +++ b/src/Verify/Combinations/CombinationResultsConverter.cs @@ -24,7 +24,7 @@ public override void Write(VerifyJsonWriter writer, CombinationResults results) for (var keyIndex = 0; keyIndex < keysLength; keyIndex++) { var key = item.Keys[keyIndex]; - var name = VerifierSettings.GetNameForParameter(key, pathFriendly: false); + var name = VerifierSettings.GetNameForParameter(key, writer.Counter, pathFriendly: false); keyValues[itemIndex, keyIndex] = name; var currentKeyLength = maxKeyLengths[keyIndex]; if (name.Length > currentKeyLength) diff --git a/src/Verify/Counter.cs b/src/Verify/Counter.cs index f1672681c..6e74324d8 100644 --- a/src/Verify/Counter.cs +++ b/src/Verify/Counter.cs @@ -12,6 +12,76 @@ public partial class Counter bool dateCounting; static AsyncLocal local = new(); + internal bool TryGetNamed(object value, [NotNullWhen(true)] out string? result) + { +#if NET6_0_OR_GREATER + + if (value is Date date) + { + if (namedDates.TryGetValue(date, out result) || + globalNamedDates.TryGetValue(date, out result)) + { + return true; + } + + result = null; + return false; + } + + if (value is Time time) + { + if (namedTimes.TryGetValue(time, out result) || + globalNamedTimes.TryGetValue(time, out result)) + { + return true; + } + + result = null; + return false; + } + +#endif + + if (value is Guid guid) + { + if (namedGuids.TryGetValue(guid, out result) || + globalNamedGuids.TryGetValue(guid, out result)) + { + return true; + } + + result = null; + return false; + } + + if (value is DateTime dateTime) + { + if (namedDateTimes.TryGetValue(dateTime, out result) || + globalNamedDateTimes.TryGetValue(dateTime, out result)) + { + return true; + } + + result = null; + return false; + } + + if (value is DateTimeOffset dateTimeOffset) + { + if (namedDateTimeOffsets.TryGetValue(dateTimeOffset, out result) || + globalNamedDateTimeOffsets.TryGetValue(dateTimeOffset, out result)) + { + return true; + } + + result = null; + return false; + } + + result = null; + return false; + } + public static Counter Current { get @@ -26,7 +96,7 @@ public static Counter Current } } - Counter( + public Counter( bool dateCounting, #if NET6_0_OR_GREATER Dictionary namedDates, diff --git a/src/Verify/Naming/FileNameBuilder.cs b/src/Verify/Naming/FileNameBuilder.cs index d0982485e..cc6ab027b 100644 --- a/src/Verify/Naming/FileNameBuilder.cs +++ b/src/Verify/Naming/FileNameBuilder.cs @@ -21,7 +21,7 @@ public static string GetTypeAndMethod(string method, string type, VerifySettings return $"{type}.{method}"; } - public static (string receivedParameters, string verifiedParameters) GetParameterText(IReadOnlyList? methodParameters, VerifySettings settings) + public static (string receivedParameters, string verifiedParameters) GetParameterText(IReadOnlyList? methodParameters, VerifySettings settings, Counter counter) { if (settings.parametersText is not null) { @@ -56,8 +56,8 @@ public static (string receivedParameters, string verifiedParameters) GetParamete var hashParameters = settings.hashParameters; return ( - BuildParameterString(allValues, hashParameters), - BuildParameterString(verifiedValues, hashParameters)); + BuildParameterString(allValues, hashParameters, counter), + BuildParameterString(verifiedValues, hashParameters, counter)); } static IEnumerable> GetVerifiedValues(HashSet? ignored, KeyValuePair[] allValues) @@ -75,7 +75,7 @@ public static (string receivedParameters, string verifiedParameters) GetParamete return allValues.Where(_ => !ignored.Contains(_.Key)); } - static string BuildParameterString(IEnumerable> values, bool hashParameters) + static string BuildParameterString(IEnumerable> values, bool hashParameters, Counter counter) { var builder = values.Aggregate( new StringBuilder(), @@ -84,7 +84,7 @@ static string BuildParameterString(IEnumerable> va acc.Append('_'); acc.Append(seed.Key); acc.Append('='); - VerifierSettings.AppendParameter(seed.Value, acc, true); + VerifierSettings.AppendParameter(seed.Value, acc, true, counter); return acc; }); diff --git a/src/Verify/Naming/VerifierSettings.cs b/src/Verify/Naming/VerifierSettings.cs index 22c02d24e..b33f06814 100644 --- a/src/Verify/Naming/VerifierSettings.cs +++ b/src/Verify/Naming/VerifierSettings.cs @@ -67,7 +67,11 @@ public static string GetNameForParameter(object? parameter) => GetNameForParameter(parameter, true); // ReSharper disable once MethodOverloadWithOptionalParameter - public static string GetNameForParameter(object? parameter, bool pathFriendly = true) + public static string GetNameForParameter(object? parameter, bool pathFriendly = true) => + GetNameForParameter(parameter, null, pathFriendly); + + // ReSharper disable once MethodOverloadWithOptionalParameter + public static string GetNameForParameter(object? parameter, Counter? counter = null, bool pathFriendly = true) { if (parameter is null) { @@ -75,11 +79,11 @@ public static string GetNameForParameter(object? parameter, bool pathFriendly = } var builder = new StringBuilder(); - AppendParameter(parameter, builder, true, pathFriendly); + AppendParameter(parameter, builder, true, counter ?? Counter.Current, pathFriendly); return builder.ToString(); } - internal static void AppendParameter(object? parameter, StringBuilder builder, bool isRoot, bool pathFriendly = true) + internal static void AppendParameter(object? parameter, StringBuilder builder, bool isRoot, Counter counter, bool pathFriendly = true) { while (true) { @@ -89,6 +93,12 @@ internal static void AppendParameter(object? parameter, StringBuilder builder, b return; } + if (counter.TryGetNamed(parameter, out var result)) + { + builder.Append(result); + return; + } + if (parameter is string stringParameter) { if (pathFriendly) @@ -126,7 +136,7 @@ internal static void AppendParameter(object? parameter, StringBuilder builder, b foreach (var item in enumerable) { - AppendParameter(item, builder, false); + AppendParameter(item, builder, false, counter); builder.Append(','); } @@ -142,7 +152,7 @@ internal static void AppendParameter(object? parameter, StringBuilder builder, b if (TryGetKeyValue(type, parameter, out var key, out var value)) { - AppendParameter(key, builder, true, pathFriendly); + AppendParameter(key, builder, true, counter, pathFriendly); builder.Append('='); parameter = value; isRoot = true; @@ -164,6 +174,7 @@ internal static void AppendParameter(object? parameter, StringBuilder builder, b { builder.Append(nameForParameter); } + break; } } diff --git a/src/Verify/Verifier/InnerVerifier.cs b/src/Verify/Verifier/InnerVerifier.cs index c54a3f304..253af7baf 100644 --- a/src/Verify/Verifier/InnerVerifier.cs +++ b/src/Verify/Verifier/InnerVerifier.cs @@ -48,14 +48,15 @@ public InnerVerifier( this.typeName = typeName; this.methodName = methodName; var typeAndMethod = FileNameBuilder.GetTypeAndMethod(methodName, typeName, settings, pathInfo); - var (receivedParameters, verifiedParameters) = FileNameBuilder.GetParameterText(methodParameters, settings); + + counter = StartCounter(settings); + + var (receivedParameters, verifiedParameters) = FileNameBuilder.GetParameterText(methodParameters, settings, counter); var namer = settings.Namer; directory = ResolveDirectory(sourceFile, settings, pathInfo); - counter = StartCounter(settings); - IoHelpers.CreateDirectory(directory); if (settings.useUniqueDirectory)