diff --git a/docs/named-tuples.md b/docs/named-tuples.md
index 3baafada80..830c6a92c3 100644
--- a/docs/named-tuples.md
+++ b/docs/named-tuples.md
@@ -19,7 +19,7 @@ Given a method that returns a named tuple:
static (bool Member1, string Member2, string Member3) MethodWithNamedTuple() =>
(true, "A", "B");
```
-snippet source | anchor
+snippet source | anchor
Can be verified:
@@ -29,7 +29,7 @@ Can be verified:
```cs
await VerifyTuple(() => MethodWithNamedTuple());
```
-snippet source | anchor
+snippet source | anchor
Resulting in:
diff --git a/docs/scrubbers.md b/docs/scrubbers.md
index c796059ace..9f99ba2dec 100644
--- a/docs/scrubbers.md
+++ b/docs/scrubbers.md
@@ -59,7 +59,7 @@ For example remove lines containing `text`:
```cs
verifySettings.ScrubLines(line => line.Contains("text"));
```
-snippet source | anchor
+snippet source | anchor
@@ -74,7 +74,7 @@ For example remove lines containing `text1` or `text2`
```cs
verifySettings.ScrubLinesContaining("text1", "text2");
```
-snippet source | anchor
+snippet source | anchor
Case insensitive by default (StringComparison.OrdinalIgnoreCase).
@@ -86,7 +86,7 @@ Case insensitive by default (StringComparison.OrdinalIgnoreCase).
```cs
verifySettings.ScrubLinesContaining(StringComparison.Ordinal, "text1", "text2");
```
-snippet source | anchor
+snippet source | anchor
@@ -101,7 +101,7 @@ For example converts lines to upper case:
```cs
verifySettings.ScrubLinesWithReplace(line => line.ToUpper());
```
-snippet source | anchor
+snippet source | anchor
@@ -114,7 +114,7 @@ Replaces `Environment.MachineName` with `TheMachineName`.
```cs
verifySettings.ScrubMachineName();
```
-snippet source | anchor
+snippet source | anchor
@@ -127,7 +127,7 @@ Replaces `Environment.UserName` with `TheUserName`.
```cs
verifySettings.ScrubUserName();
```
-snippet source | anchor
+snippet source | anchor
diff --git a/docs/serializer-settings.md b/docs/serializer-settings.md
index fdeb6481de..0ddc67bf24 100644
--- a/docs/serializer-settings.md
+++ b/docs/serializer-settings.md
@@ -85,7 +85,7 @@ var settings = new JsonSerializerSettings
DefaultValueHandling = DefaultValueHandling.Ignore,
};
```
-snippet source | anchor
+snippet source | anchor
@@ -157,7 +157,7 @@ To disable this behavior globally use:
```cs
VerifierSettings.DontIgnoreEmptyCollections();
```
-snippet source | anchor
+snippet source | anchor
@@ -179,7 +179,7 @@ var target = new GuidTarget
await Verify(target);
```
-snippet source | anchor
+snippet source | anchor
Results in the following:
@@ -204,7 +204,7 @@ Strings containing inline Guids can also be scrubbed. To enable this behavior, u
```cs
VerifierSettings.ScrubInlineGuids();
```
-snippet source | anchor
+snippet source | anchor
@@ -240,7 +240,7 @@ To disable this behavior globally use:
```cs
VerifierSettings.DontScrubGuids();
```
-snippet source | anchor
+snippet source | anchor
@@ -304,7 +304,7 @@ var target = new DateTimeTarget
await Verify(target);
```
-snippet source | anchor
+snippet source | anchor
Results in the following:
@@ -342,7 +342,7 @@ settings.DontScrubDateTimes();
return Verify(target, settings);
```
-snippet source | anchor
+snippet source | anchor
Or using the fluent api use:
@@ -358,7 +358,7 @@ var target = new
return Verify(target)
.DontScrubDateTimes();
```
-snippet source | anchor
+snippet source | anchor
Or globally use:
@@ -368,7 +368,7 @@ Or globally use:
```cs
VerifierSettings.DontScrubDateTimes();
```
-snippet source | anchor
+snippet source | anchor
@@ -411,7 +411,7 @@ await Verify(target)
.AddNamedDateTime(new(2030, 1, 2), "instanceNamedDateTime")
.AddNamedDateTimeOffset(new DateTime(2030, 1, 2), "instanceNamedTimeOffset");
```
-snippet source | anchor
+snippet source | anchor
@@ -429,7 +429,7 @@ public static void AddNamedDatesAndTimes()
VerifierSettings.AddNamedDateTimeOffset(new(new(2030, 1, 1)), "namedDateTimeOffset");
}
```
-snippet source | anchor
+snippet source | anchor
@@ -563,7 +563,7 @@ public Task ScopedSerializerFluent()
.AddExtraSettings(_ => _.TypeNameHandling = TypeNameHandling.All);
}
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -691,7 +691,7 @@ public Task IgnoreTypeFluent()
.IgnoreMembersWithType();
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -701,7 +701,7 @@ Or globally:
```cs
VerifierSettings.IgnoreMembersWithType();
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -838,7 +838,7 @@ public Task ScrubTypeFluent()
.ScrubMembersWithType();
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -848,7 +848,7 @@ Or globally:
```cs
VerifierSettings.ScrubMembersWithType();
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -927,7 +927,7 @@ public Task AddIgnoreInstanceFluent()
.IgnoreInstance(_ => _.Property == "Ignore");
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -937,7 +937,7 @@ Or globally:
```cs
VerifierSettings.IgnoreInstance(_ => _.Property == "Ignore");
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -999,7 +999,7 @@ public Task AddScrubInstanceFluent()
.ScrubInstance(_ => _.Property == "Ignore");
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -1009,7 +1009,7 @@ Or globally:
```cs
VerifierSettings.ScrubInstance(_ => _.Property == "Ignore");
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1054,7 +1054,7 @@ public Task WithObsoleteProp()
return Verify(target);
}
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1102,7 +1102,7 @@ public Task WithObsoletePropIncludedFluent()
.IncludeObsoletes();
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -1112,7 +1112,7 @@ Or globally:
```cs
VerifierSettings.IncludeObsoletes();
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1173,7 +1173,7 @@ public Task IgnoreMemberByExpressionFluent()
_ => _.PropertyThatThrows);
}
```
-snippet source | anchor
+snippet source | anchor
Or globally
@@ -1188,7 +1188,7 @@ VerifierSettings.IgnoreMembers(
_ => _.GetOnlyProperty,
_ => _.PropertyThatThrows);
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1248,7 +1248,7 @@ public Task ScrubMemberByExpressionFluent()
_ => _.PropertyThatThrows);
}
```
-snippet source | anchor
+snippet source | anchor
Or globally
@@ -1263,7 +1263,7 @@ VerifierSettings.ScrubMembers(
_ => _.GetOnlyProperty,
_ => _.PropertyThatThrows);
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1342,7 +1342,7 @@ public Task IgnoreMemberByNameFluent()
.IgnoreMember(_ => _.PropertyThatThrows);
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -1362,7 +1362,7 @@ VerifierSettings.IgnoreMember("Field");
// For a specific type with expression
VerifierSettings.IgnoreMember(_ => _.PropertyThatThrows);
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1437,7 +1437,7 @@ public Task ScrubMemberByNameFluent()
.ScrubMember(_ => _.PropertyThatThrows);
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -1457,7 +1457,7 @@ VerifierSettings.ScrubMember("Field");
// For a specific type with expression
VerifierSettings.ScrubMember(_ => _.PropertyThatThrows);
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1508,7 +1508,7 @@ public Task CustomExceptionPropFluent()
.IgnoreMembersThatThrow();
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -1518,7 +1518,7 @@ Or globally:
```cs
VerifierSettings.IgnoreMembersThatThrow();
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1555,7 +1555,7 @@ public Task ExceptionMessagePropFluent()
.IgnoreMembersThatThrow(_ => _.Message == "Ignore");
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -1565,7 +1565,7 @@ Or globally:
```cs
VerifierSettings.IgnoreMembersThatThrow(_ => _.Message == "Ignore");
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1689,7 +1689,7 @@ public Task MemberConverterByExpression()
return Verify(input);
}
```
-snippet source | anchor
+snippet source | anchor
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 9ae84778c7..6288cf9ba6 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -2,7 +2,7 @@
CS1591;CS0649;xUnit1026;xUnit1013;msb3277;CS0436;CS1573
- 19.11.2
+ 19.12.0
enable
11
true
diff --git a/src/StrictJsonTests/SerializationTests.StringDictionary.verified.json b/src/StrictJsonTests/SerializationTests.StringDictionary.verified.json
new file mode 100644
index 0000000000..ccddb17234
--- /dev/null
+++ b/src/StrictJsonTests/SerializationTests.StringDictionary.verified.json
@@ -0,0 +1,12 @@
+{
+ "item2": {
+ "key": null
+ },
+ "item4": {
+ "key": "value"
+ },
+ "item8": {
+ "key1": "value1",
+ "key2": "value2"
+ }
+}
\ No newline at end of file
diff --git a/src/Verify.Tests/Serialization/SerializationTests.StringDictionary.verified.txt b/src/Verify.Tests/Serialization/SerializationTests.StringDictionary.verified.txt
new file mode 100644
index 0000000000..f9ee86ae50
--- /dev/null
+++ b/src/Verify.Tests/Serialization/SerializationTests.StringDictionary.verified.txt
@@ -0,0 +1,12 @@
+{
+ item2: {
+ key: null
+ },
+ item4: {
+ key: value
+ },
+ item8: {
+ key1: value1,
+ key2: value2
+ }
+}
\ No newline at end of file
diff --git a/src/Verify.Tests/Serialization/SerializationTests.cs b/src/Verify.Tests/Serialization/SerializationTests.cs
index 87b595da45..35ebf0ac38 100644
--- a/src/Verify.Tests/Serialization/SerializationTests.cs
+++ b/src/Verify.Tests/Serialization/SerializationTests.cs
@@ -679,6 +679,35 @@ public Task NameValueCollection() =>
}
});
+
+ [Fact]
+ public Task StringDictionary() =>
+ Verify(
+ new
+ {
+ item2 = new StringDictionary
+ {
+ {
+ "key", null
+ }
+ },
+ item4 = new StringDictionary
+ {
+ {
+ "key", "value"
+ }
+ },
+ item8 = new StringDictionary
+ {
+ {
+ "key1", "value1"
+ },
+ {
+ "key2", "value2"
+ }
+ }
+ });
+
[Fact]
public Task Timespan() =>
Verify(
diff --git a/src/Verify/Serialization/Converters/StringDictionaryConverter.cs b/src/Verify/Serialization/Converters/StringDictionaryConverter.cs
new file mode 100644
index 0000000000..4b5409cda3
--- /dev/null
+++ b/src/Verify/Serialization/Converters/StringDictionaryConverter.cs
@@ -0,0 +1,16 @@
+class StringDictionaryConverter :
+ WriteOnlyJsonConverter
+{
+ public override void Write(VerifyJsonWriter writer, StringDictionary collection)
+ {
+ var dictionary = new Dictionary(collection.Count);
+ foreach (string? key in collection.Keys)
+ {
+ var notNullKey = key!;
+ var value = collection[notNullKey];
+ dictionary[notNullKey] = value;
+ }
+
+ writer.Serialize(dictionary);
+ }
+}
\ No newline at end of file
diff --git a/src/Verify/Serialization/SerializationSettings.cs b/src/Verify/Serialization/SerializationSettings.cs
index deeef7e0f6..8232241276 100644
--- a/src/Verify/Serialization/SerializationSettings.cs
+++ b/src/Verify/Serialization/SerializationSettings.cs
@@ -27,6 +27,7 @@ partial class SerializationSettings
static ClaimsPrincipalConverter claimsPrincipalConverter = new();
static ClaimsIdentityConverter claimsIdentityConverter = new();
static NameValueCollectionConverter nameValueCollectionConverter = new();
+ static StringDictionaryConverter stringDictionaryConverter = new();
static StringBuilderConverter stringBuilderConverter = new();
static TaskConverter taskConverter = new();
static ValueTaskConverter valueTaskConverter = new();
@@ -118,6 +119,7 @@ JsonSerializerSettings BuildSettings()
converters.Add(jArrayConverter);
converters.Add(jObjectConverter);
converters.Add(nameValueCollectionConverter);
+ converters.Add(stringDictionaryConverter);
converters.Add(keyValuePairConverter);
foreach (var extraSetting in extraSettings)
{