From 8e1e9452579ea5c3e51bc4dc5f1ad2a52869d8f5 Mon Sep 17 00:00:00 2001 From: Shubhra Mittal Date: Thu, 3 Sep 2026 20:42:31 +0100 Subject: [PATCH] Fix converter priority for extra settings Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../SerializationSettingsTests.cs | 91 +++++++++++++++++++ .../Serialization/SerializationSettings.cs | 39 ++++++++ 2 files changed, 130 insertions(+) create mode 100644 src/Verify.Tests/Serialization/SerializationSettingsTests.cs diff --git a/src/Verify.Tests/Serialization/SerializationSettingsTests.cs b/src/Verify.Tests/Serialization/SerializationSettingsTests.cs new file mode 100644 index 000000000..9be46e48f --- /dev/null +++ b/src/Verify.Tests/Serialization/SerializationSettingsTests.cs @@ -0,0 +1,91 @@ +public class SerializationSettingsTests +{ + [Fact] + public void ExtraConverterOverridesBuiltIn() + { + var converter = new CustomEnumConverter(); + var settings = new SerializationSettings(); + settings.AddExtraSettings(_ => _.Converters.Add(converter)); + + AssertUsesConverter(settings, converter); + AssertUsesConverter(new(settings), converter); + } + + [Fact] + public void ExtraSettingsPreserveOrder() + { + var first = new CustomEnumConverter(); + var second = new CustomEnumConverter(); + var settings = new SerializationSettings(); + settings.AddExtraSettings( + _ => + { + _.Converters.Add(first); + _.ReferenceLoopHandling = ReferenceLoopHandling.Serialize; + }); + settings.AddExtraSettings( + _ => + { + Assert.Equal(ReferenceLoopHandling.Serialize, _.ReferenceLoopHandling); + _.Converters.Add(second); + _.ReferenceLoopHandling = ReferenceLoopHandling.Error; + }); + + AssertOrder(settings, first, second); + AssertOrder(new(settings), first, second); + } + + [Fact] + public void ExplicitConverterPositionIsPreserved() + { + var first = new CustomEnumConverter(); + var second = new CustomEnumConverter(); + var settings = new SerializationSettings(); + settings.AddExtraSettings(_ => _.Converters.Add(first)); + settings.AddExtraSettings(_ => _.Converters.Insert(0, second)); + + AssertOrder(settings, second, first); + AssertOrder(new(settings), second, first); + } + + [Fact] + public void RemovedConverterDoesNotAffectPriority() + { + var removed = new CustomEnumConverter(); + var first = new CustomEnumConverter(); + var second = new CustomEnumConverter(); + var settings = new SerializationSettings(); + settings.AddExtraSettings(_ => _.Converters.Add(removed)); + settings.AddExtraSettings(_ => _.Converters.Add(first)); + settings.AddExtraSettings( + _ => + { + _.Converters.Remove(removed); + _.Converters.Add(second); + }); + + AssertOrder(settings, first, second); + AssertOrder(new(settings), first, second); + } + + static void AssertOrder(SerializationSettings settings, JsonConverter first, JsonConverter second) + { + Assert.Same(first, settings.Serializer.Converters[0]); + Assert.Same(second, settings.Serializer.Converters[1]); + } + + static void AssertUsesConverter(SerializationSettings settings, JsonConverter converter) + => Assert.Same(converter, settings.Serializer.Converters[0]); + + class CustomEnumConverter : + WriteOnlyJsonConverter + { + public override void Write(VerifyJsonWriter writer, TestEnum value) => + writer.WriteValue("custom"); + } + + enum TestEnum + { + Value + } +} diff --git a/src/Verify/Serialization/SerializationSettings.cs b/src/Verify/Serialization/SerializationSettings.cs index 866f4e6e7..39949401d 100644 --- a/src/Verify/Serialization/SerializationSettings.cs +++ b/src/Verify/Serialization/SerializationSettings.cs @@ -37,6 +37,7 @@ partial class SerializationSettings static CombinationResultsConverter combinationResultsConverter = new(); JsonSerializerSettings jsonSettings; + List builtInConverters = []; public SerializationSettings() { @@ -132,6 +133,7 @@ JsonSerializerSettings BuildSettings() converters.Add(stringDictionaryConverter); converters.Add(keyValuePairConverter); converters.Add(combinationResultsConverter); + builtInConverters = converters.ToList(); foreach (var extraSetting in extraSettings) { ApplyExtraSetting(settings, extraSetting); @@ -154,6 +156,8 @@ void ApplyExtraSetting(JsonSerializerSettings settings, Action converters) + { + var remainingBuiltIns = builtInConverters.ToList(); + var extras = new List(); + var builtIns = new List(); + foreach (var converter in converters) + { + var index = remainingBuiltIns.FindIndex(_ => ReferenceEquals(_, converter)); + if (index < 0) + { + extras.Add(converter); + continue; + } + + remainingBuiltIns.RemoveAt(index); + builtIns.Add(converter); + } + + if (extras.Count == 0) + { + return; + } + + converters.Clear(); + foreach (var converter in extras) + { + converters.Add(converter); + } + + foreach (var converter in builtIns) + { + converters.Add(converter); + } + } + public void AddExtraSettings(Action action) { extraSettings.Add(action);