Skip to content

Commit c13a5db

Browse files
committed
.
1 parent 01615db commit c13a5db

File tree

3 files changed

+34
-15
lines changed

3 files changed

+34
-15
lines changed

src/Verify/Serialization/Scrubbers/VerifierSettings.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
public static partial class VerifierSettings
44
{
5-
static VerifierSettings() =>
5+
static VerifierSettings()
6+
{
7+
InitBuiltInTypedConverters();
8+
69
MemberConverter<Exception, string>(
710
_ => _.StackTrace,
811
(_, value) =>
@@ -14,4 +17,5 @@ static VerifierSettings() =>
1417

1518
return ScrubStackTrace.Scrub(value);
1619
});
20+
}
1721
}

src/Verify/Splitters/Settings_Typed.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@
22

33
public static partial class VerifierSettings
44
{
5-
static List<TypeConverter> typedConverters = [];
5+
static List<TypeConverter> typedConverters = null!;
6+
7+
static void InitBuiltInTypedConverters() =>
8+
typedConverters =
9+
[
10+
// StringBuilder - use "txt" extension
11+
new(
12+
(target, _) => Task.FromResult(new ConversionResult(null, "txt", (StringBuilder) target)),
13+
(target, _) => target is StringBuilder)
14+
];
615

716
internal static bool TryGetTypedConverter<T>(
817
T target,
@@ -37,7 +46,8 @@ public static void RegisterFileConverter<T>(
3746
{
3847
InnerVerifier.ThrowIfVerifyHasBeenRun();
3948
var converter = new TypeConverter((target, context) => conversion((T) target, context), DefaultCanConvert(canConvert));
40-
typedConverters.Add(converter);
49+
// Insert at beginning so user converters take precedence over built-in converters
50+
typedConverters.Insert(0, converter);
4151
}
4252

4353
public static void RegisterFileConverter(
@@ -56,7 +66,8 @@ public static void RegisterFileConverter(
5666
{
5767
InnerVerifier.ThrowIfVerifyHasBeenRun();
5868
var converter = new TypeConverter(conversion, canConvert);
59-
typedConverters.Add(converter);
69+
// Insert at beginning so user converters take precedence over built-in converters
70+
typedConverters.Insert(0, converter);
6071
}
6172

6273
static CanConvert DefaultCanConvert<T>(CanConvert<T>? canConvert)

src/Verify/Verifier/InnerVerifier_Inner.cs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ async Task<VerifyResult> VerifyInner(object? root, Func<Task>? cleanup, IEnumera
9494
return (cleanup, resultTargets);
9595
}
9696

97-
async Task<(List<ResolvedTarget> targets, Func<Task> cleanup, bool applyScrubbers, List<object> converterInfos)> ResolveTarget(Target target)
97+
async Task<(List<ResolvedTarget> targets, Func<Task> cleanup, bool applyScrubbers, List<object> converterInfos)> ResolveTarget(Target target, string? skipConverterForExtension = null)
9898
{
9999
var cleanup = () => Task.CompletedTask;
100100
var results = new List<ResolvedTarget>();
@@ -105,13 +105,23 @@ async Task<VerifyResult> VerifyInner(object? root, Func<Task>? cleanup, IEnumera
105105
{
106106
if (target.TryGetStream(out var stream))
107107
{
108-
if (target.PerformConversion)
108+
// Skip converter if same extension (prevents infinite recursion)
109+
if (target.PerformConversion && target.Extension != skipConverterForExtension)
109110
{
110111
var (streamResults, streamCleanup, infos) = await ResolveStream(stream, target.Extension, target.Name);
111112
return (streamResults, streamCleanup, true, infos);
112113
}
113114

114-
results.Add(new(target.Extension, stream, target.Name));
115+
// Direct conversion without converter
116+
stream.MoveToStart();
117+
if (FileExtensions.IsTextExtension(target.Extension))
118+
{
119+
results.Add(new(target.Extension, await stream.ReadStringBuilderWithFixedLines(), target.Name));
120+
}
121+
else
122+
{
123+
results.Add(new(target.Extension, stream, target.Name));
124+
}
115125
}
116126
else if (target.TryGetStringBuilder(out var sb))
117127
{
@@ -180,13 +190,6 @@ async Task<VerifyResult> VerifyInner(object? root, Func<Task>? cleanup, IEnumera
180190
throw new("Use Verify(IEnumerable<T> targets, string extension)");
181191
}
182192

183-
// Handle StringBuilder - apply scrubbers
184-
if (data is StringBuilder sb2)
185-
{
186-
results.Add(new("txt", sb2, target.Name));
187-
return (results, cleanup, true, converterInfos);
188-
}
189-
190193
// Handle string - check for JSON appenders first (matches TryGetRootTarget behavior)
191194
if (data is string str)
192195
{
@@ -286,9 +289,10 @@ async Task<VerifyResult> VerifyInner(object? root, Func<Task>? cleanup, IEnumera
286289
}
287290

288291
// Recursively resolve converted targets (they may contain objects)
292+
// Pass extension to prevent infinite recursion for same-extension targets
289293
foreach (var convTarget in converted)
290294
{
291-
var (resolved, resolveCleanup, _, nestedInfos) = await ResolveTarget(convTarget);
295+
var (resolved, resolveCleanup, _, nestedInfos) = await ResolveTarget(convTarget, extension);
292296
cleanup += resolveCleanup;
293297
results.AddRange(resolved);
294298
converterInfos.AddRange(nestedInfos);

0 commit comments

Comments
 (0)