diff --git a/docs/dates.md b/docs/dates.md
index 1e9d1a244..ecc3e834a 100644
--- a/docs/dates.md
+++ b/docs/dates.md
@@ -29,7 +29,7 @@ var target = new DateTimeTarget
await Verify(target);
```
-snippet source | anchor
+snippet source | anchor
Results in the following:
@@ -70,7 +70,7 @@ settings.DontScrubDateTimes();
return Verify(target, settings);
```
-snippet source | anchor
+snippet source | anchor
@@ -87,7 +87,7 @@ var target = new
return Verify(target)
.DontScrubDateTimes();
```
-snippet source | anchor
+snippet source | anchor
@@ -100,7 +100,7 @@ return Verify(target)
public static void ModuleInitializer() =>
VerifierSettings.DontScrubDateTimes();
```
-snippet source | anchor
+snippet source | anchor
@@ -124,7 +124,7 @@ settings.DisableDateCounting();
return Verify(target, settings);
```
-snippet source | anchor
+snippet source | anchor
@@ -141,7 +141,7 @@ var target = new
return Verify(target)
.DisableDateCounting();
```
-snippet source | anchor
+snippet source | anchor
@@ -154,7 +154,7 @@ return Verify(target)
public static void ModuleInitializer() =>
VerifierSettings.DisableDateCounting();
```
-snippet source | anchor
+snippet source | anchor
@@ -201,7 +201,7 @@ public Task ScrubInlineDateTimesInstance()
settings);
}
```
-snippet source | anchor
+snippet source | anchor
@@ -215,7 +215,7 @@ public Task ScrubInlineDateTimesFluent() =>
Verify("content 2020-10-20 content")
.ScrubInlineDateTimes("yyyy-MM-dd");
```
-snippet source | anchor
+snippet source | anchor
@@ -231,7 +231,7 @@ public static class ModuleInitializer
VerifierSettings.ScrubInlineDateTimes("yyyy-MM-dd");
}
```
-snippet source | anchor
+snippet source | anchor
@@ -252,7 +252,7 @@ settings.AddNamedDateTime(new(2030, 1, 2), "instanceNamedDateTime");
settings.AddNamedDateTimeOffset(new DateTime(2030, 1, 2), "instanceNamedTimeOffset");
await Verify(target, settings);
```
-snippet source | anchor
+snippet source | anchor
@@ -267,7 +267,7 @@ await Verify(target)
.AddNamedDateTime(new(2030, 1, 2), "instanceNamedDateTime")
.AddNamedDateTimeOffset(new DateTime(2030, 1, 2), "instanceNamedTimeOffset");
```
-snippet source | anchor
+snippet source | anchor
@@ -285,7 +285,7 @@ public static void NamedDatesAndTimesGlobal()
VerifierSettings.AddNamedDateTimeOffset(new(new(2030, 1, 1)), "namedDateTimeOffset");
}
```
-snippet source | anchor
+snippet source | anchor
diff --git a/docs/guids.md b/docs/guids.md
index 7d4f45e84..2ca00fa83 100644
--- a/docs/guids.md
+++ b/docs/guids.md
@@ -23,7 +23,7 @@ var target = new GuidTarget
await Verify(target);
```
-snippet source | anchor
+snippet source | anchor
Results in the following:
@@ -79,7 +79,7 @@ await Verify(target)
```cs
VerifierSettings.DontScrubGuids();
```
-snippet source | anchor
+snippet source | anchor
@@ -103,7 +103,7 @@ public Task ScrubInlineGuidsInstance()
settings);
}
```
-snippet source | anchor
+snippet source | anchor
@@ -117,7 +117,7 @@ public Task ScrubInlineGuidsFluent() =>
Verify("content 651ad409-fc30-4b12-a47e-616d3f953e4c content")
.ScrubInlineGuids();
```
-snippet source | anchor
+snippet source | anchor
@@ -133,7 +133,7 @@ public static class ModuleInitializer
VerifierSettings.ScrubInlineGuids();
}
```
-snippet source | anchor
+snippet source | anchor
diff --git a/docs/named-tuples.md b/docs/named-tuples.md
index 151cc9822..8f2da6526 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 6458f9e2f..790a9799f 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 c8baaa757..df99f2775 100644
--- a/docs/serializer-settings.md
+++ b/docs/serializer-settings.md
@@ -246,7 +246,7 @@ To disable this behavior globally use:
```cs
VerifierSettings.DontIgnoreEmptyCollections();
```
-snippet source | anchor
+snippet source | anchor
@@ -347,7 +347,7 @@ public Task ScopedSerializerFluent()
.AddExtraSettings(_ => _.TypeNameHandling = TypeNameHandling.All);
}
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -475,7 +475,7 @@ public Task IgnoreTypeFluent()
.IgnoreMembersWithType();
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -485,7 +485,7 @@ Or globally:
```cs
VerifierSettings.IgnoreMembersWithType();
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -622,7 +622,7 @@ public Task ScrubTypeFluent()
.ScrubMembersWithType();
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -632,7 +632,7 @@ Or globally:
```cs
VerifierSettings.ScrubMembersWithType();
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -711,7 +711,7 @@ public Task AddIgnoreInstanceFluent()
.IgnoreInstance(_ => _.Property == "Ignore");
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -721,7 +721,7 @@ Or globally:
```cs
VerifierSettings.IgnoreInstance(_ => _.Property == "Ignore");
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -783,7 +783,7 @@ public Task AddScrubInstanceFluent()
.ScrubInstance(_ => _.Property == "Ignore");
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -793,7 +793,7 @@ Or globally:
```cs
VerifierSettings.ScrubInstance(_ => _.Property == "Ignore");
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -838,7 +838,7 @@ public Task WithObsoleteProp()
return Verify(target);
}
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -886,7 +886,7 @@ public Task WithObsoletePropIncludedFluent()
.IncludeObsoletes();
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -896,7 +896,7 @@ Or globally:
```cs
VerifierSettings.IncludeObsoletes();
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -957,7 +957,7 @@ public Task IgnoreMemberByExpressionFluent()
_ => _.PropertyThatThrows);
}
```
-snippet source | anchor
+snippet source | anchor
Or globally
@@ -972,7 +972,7 @@ VerifierSettings.IgnoreMembers(
_ => _.GetOnlyProperty,
_ => _.PropertyThatThrows);
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1032,7 +1032,7 @@ public Task ScrubMemberByExpressionFluent()
_ => _.PropertyThatThrows);
}
```
-snippet source | anchor
+snippet source | anchor
Or globally
@@ -1047,7 +1047,7 @@ VerifierSettings.ScrubMembers(
_ => _.GetOnlyProperty,
_ => _.PropertyThatThrows);
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1126,7 +1126,7 @@ public Task IgnoreMemberByNameFluent()
.IgnoreMember(_ => _.PropertyThatThrows);
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -1146,7 +1146,7 @@ VerifierSettings.IgnoreMember("Field");
// For a specific type with expression
VerifierSettings.IgnoreMember(_ => _.PropertyThatThrows);
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1221,7 +1221,7 @@ public Task ScrubMemberByNameFluent()
.ScrubMember(_ => _.PropertyThatThrows);
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -1241,7 +1241,7 @@ VerifierSettings.ScrubMember("Field");
// For a specific type with expression
VerifierSettings.ScrubMember(_ => _.PropertyThatThrows);
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1292,7 +1292,7 @@ public Task CustomExceptionPropFluent()
.IgnoreMembersThatThrow();
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -1302,7 +1302,7 @@ Or globally:
```cs
VerifierSettings.IgnoreMembersThatThrow();
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1339,7 +1339,7 @@ public Task ExceptionMessagePropFluent()
.IgnoreMembersThatThrow(_ => _.Message == "Ignore");
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -1349,7 +1349,7 @@ Or globally:
```cs
VerifierSettings.IgnoreMembersThatThrow(_ => _.Message == "Ignore");
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1507,7 +1507,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 c15b71cb9..fdda4e9df 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -2,7 +2,7 @@
CS1591;CS0649;xUnit1026;xUnit1013;CS1573;VerifyTestsProjectDir;VerifySetParameters;PolyFillTargetsForNuget
- 28.2.0
+ 28.2.1
enable
preview
1.0.0
diff --git a/src/StrictJsonTests/SerializationTests.NullProperty.verified.json b/src/StrictJsonTests/SerializationTests.NullProperty.verified.json
new file mode 100644
index 000000000..cca15c585
--- /dev/null
+++ b/src/StrictJsonTests/SerializationTests.NullProperty.verified.json
@@ -0,0 +1,3 @@
+{
+ "property": "value1"
+}
\ No newline at end of file
diff --git a/src/StrictJsonTests/SerializationTests.NullPropertyInclude.verified.json b/src/StrictJsonTests/SerializationTests.NullPropertyInclude.verified.json
new file mode 100644
index 000000000..be84441d7
--- /dev/null
+++ b/src/StrictJsonTests/SerializationTests.NullPropertyInclude.verified.json
@@ -0,0 +1,3 @@
+{
+ "nullProperty": null
+}
\ No newline at end of file
diff --git a/src/StrictJsonTests/SerializationTests.WithWriteMemberNull.verified.json b/src/StrictJsonTests/SerializationTests.WithWriteMemberNull.verified.json
new file mode 100644
index 000000000..22fdca1b2
--- /dev/null
+++ b/src/StrictJsonTests/SerializationTests.WithWriteMemberNull.verified.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/src/StrictJsonTests/SerializationTests.WithWriteMemberNullIgnored.verified.json b/src/StrictJsonTests/SerializationTests.WithWriteMemberNullIgnored.verified.json
new file mode 100644
index 000000000..22fdca1b2
--- /dev/null
+++ b/src/StrictJsonTests/SerializationTests.WithWriteMemberNullIgnored.verified.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/src/StrictJsonTests/SerializationTests.WithWriteMemberNullIgnored_Include.verified.json b/src/StrictJsonTests/SerializationTests.WithWriteMemberNullIgnored_Include.verified.json
new file mode 100644
index 000000000..22fdca1b2
--- /dev/null
+++ b/src/StrictJsonTests/SerializationTests.WithWriteMemberNullIgnored_Include.verified.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/src/StrictJsonTests/SerializationTests.WithWriteMemberNullScrubbed.verified.json b/src/StrictJsonTests/SerializationTests.WithWriteMemberNullScrubbed.verified.json
new file mode 100644
index 000000000..4f1ebe02f
--- /dev/null
+++ b/src/StrictJsonTests/SerializationTests.WithWriteMemberNullScrubbed.verified.json
@@ -0,0 +1,3 @@
+{
+ "Name": "Scrubbed"
+}
\ No newline at end of file
diff --git a/src/StrictJsonTests/SerializationTests.WithWriteMemberNullScrubbed_Include.verified.json b/src/StrictJsonTests/SerializationTests.WithWriteMemberNullScrubbed_Include.verified.json
new file mode 100644
index 000000000..4f1ebe02f
--- /dev/null
+++ b/src/StrictJsonTests/SerializationTests.WithWriteMemberNullScrubbed_Include.verified.json
@@ -0,0 +1,3 @@
+{
+ "Name": "Scrubbed"
+}
\ No newline at end of file
diff --git a/src/StrictJsonTests/SerializationTests.WithWriteMemberNull_Include.verified.json b/src/StrictJsonTests/SerializationTests.WithWriteMemberNull_Include.verified.json
new file mode 100644
index 000000000..6ae9aeee7
--- /dev/null
+++ b/src/StrictJsonTests/SerializationTests.WithWriteMemberNull_Include.verified.json
@@ -0,0 +1,3 @@
+{
+ "Name": null
+}
\ No newline at end of file
diff --git a/src/Verify.Tests/Serialization/SerializationTests.NullProperty.verified.txt b/src/Verify.Tests/Serialization/SerializationTests.NullProperty.verified.txt
new file mode 100644
index 000000000..5e7849351
--- /dev/null
+++ b/src/Verify.Tests/Serialization/SerializationTests.NullProperty.verified.txt
@@ -0,0 +1,3 @@
+{
+ property: value1
+}
\ No newline at end of file
diff --git a/src/Verify.Tests/Serialization/SerializationTests.NullPropertyInclude.verified.txt b/src/Verify.Tests/Serialization/SerializationTests.NullPropertyInclude.verified.txt
new file mode 100644
index 000000000..7bafeb87a
--- /dev/null
+++ b/src/Verify.Tests/Serialization/SerializationTests.NullPropertyInclude.verified.txt
@@ -0,0 +1,3 @@
+{
+ nullProperty: null
+}
\ No newline at end of file
diff --git a/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNull.verified.txt b/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNull.verified.txt
new file mode 100644
index 000000000..22fdca1b2
--- /dev/null
+++ b/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNull.verified.txt
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNullIgnored.verified.txt b/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNullIgnored.verified.txt
new file mode 100644
index 000000000..22fdca1b2
--- /dev/null
+++ b/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNullIgnored.verified.txt
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNullIgnored_Include.verified.txt b/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNullIgnored_Include.verified.txt
new file mode 100644
index 000000000..22fdca1b2
--- /dev/null
+++ b/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNullIgnored_Include.verified.txt
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNullScrubbed.verified.txt b/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNullScrubbed.verified.txt
new file mode 100644
index 000000000..536441ea1
--- /dev/null
+++ b/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNullScrubbed.verified.txt
@@ -0,0 +1,3 @@
+{
+ Name: Scrubbed
+}
\ No newline at end of file
diff --git a/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNullScrubbed_Include.verified.txt b/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNullScrubbed_Include.verified.txt
new file mode 100644
index 000000000..536441ea1
--- /dev/null
+++ b/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNullScrubbed_Include.verified.txt
@@ -0,0 +1,3 @@
+{
+ Name: Scrubbed
+}
\ No newline at end of file
diff --git a/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNull_Include.verified.txt b/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNull_Include.verified.txt
new file mode 100644
index 000000000..8975db01a
--- /dev/null
+++ b/src/Verify.Tests/Serialization/SerializationTests.WithWriteMemberNull_Include.verified.txt
@@ -0,0 +1,3 @@
+{
+ Name: null
+}
\ No newline at end of file
diff --git a/src/Verify.Tests/Serialization/SerializationTests.cs b/src/Verify.Tests/Serialization/SerializationTests.cs
index 3f36a5238..0ec53ed7e 100644
--- a/src/Verify.Tests/Serialization/SerializationTests.cs
+++ b/src/Verify.Tests/Serialization/SerializationTests.cs
@@ -921,6 +921,28 @@ public Task BoolDefault()
return Verify(target);
}
+ [Fact]
+ public Task NullProperty() =>
+ Verify(
+ new
+ {
+ property ="value1",
+ nullProperty = (string?)null
+ });
+
+ [Fact]
+ public Task NullPropertyInclude() =>
+ Verify(
+ new
+ {
+ nullProperty = (string?)null
+ })
+ .AddExtraSettings(_=>
+ {
+ _.DefaultValueHandling = DefaultValueHandling.Include;
+ _.NullValueHandling = NullValueHandling.Include;
+ });
+
[Fact]
public Task BoolFalse()
{
@@ -3771,7 +3793,64 @@ public override void Write(VerifyJsonWriter writer, ConverterTarget target)
}
}
- record ConverterTarget(string Name);
+ [Fact]
+ public Task WithWriteMemberNull() =>
+ Verify(new ConverterTarget(null))
+ .AddExtraSettings(_ => _.Converters.Add(new NullConverter()));
+
+ [Fact]
+ public Task WithWriteMemberNull_Include() =>
+ Verify(new ConverterTarget(null))
+ .AddExtraSettings(_ =>
+ {
+ _.Converters.Add(new NullConverter());
+ _.NullValueHandling = NullValueHandling.Include;
+ });
+
+ [Fact]
+ public Task WithWriteMemberNullScrubbed() =>
+ Verify(new ConverterTarget(null))
+ .AddExtraSettings(_ => _.Converters.Add(new NullConverter()))
+ .ScrubMember("Name");
+
+ [Fact]
+ public Task WithWriteMemberNullScrubbed_Include() =>
+ Verify(new ConverterTarget(null))
+ .AddExtraSettings(_ =>
+ {
+ _.Converters.Add(new NullConverter());
+ _.NullValueHandling = NullValueHandling.Include;
+ })
+ .ScrubMember("Name");
+
+ [Fact]
+ public Task WithWriteMemberNullIgnored() =>
+ Verify(new ConverterTarget(null))
+ .AddExtraSettings(_ => _.Converters.Add(new NullConverter()))
+ .IgnoreMember("Name");
+
+ [Fact]
+ public Task WithWriteMemberNullIgnored_Include() =>
+ Verify(new ConverterTarget(null))
+ .AddExtraSettings(_ =>
+ {
+ _.Converters.Add(new NullConverter());
+ _.NullValueHandling = NullValueHandling.Include;
+ })
+ .IgnoreMember("Name");
+
+ class NullConverter :
+ WriteOnlyJsonConverter
+ {
+ public override void Write(VerifyJsonWriter writer, ConverterTarget target)
+ {
+ writer.WriteStartObject();
+ writer.WriteMember(target, target.Name, "Name");
+ writer.WriteEnd();
+ }
+ }
+
+ record ConverterTarget(string? Name);
[Fact]
public Task WithConverterIgnoreDefault() =>
diff --git a/src/Verify/Serialization/VerifyJsonWriter.cs b/src/Verify/Serialization/VerifyJsonWriter.cs
index e03f0db18..5ba701abf 100644
--- a/src/Verify/Serialization/VerifyJsonWriter.cs
+++ b/src/Verify/Serialization/VerifyJsonWriter.cs
@@ -209,6 +209,26 @@ public void WriteMember(object target, object? value, string name)
{
if (value is null)
{
+ if (serialization.TryGetScrubOrIgnoreByName(name, out var scrubOrIgnoreByName))
+ {
+ if (scrubOrIgnoreByName == ScrubOrIgnore.Ignore)
+ {
+ return;
+ }
+
+ WritePropertyName(name);
+ WriteRawValueIfNoStrict("Scrubbed");
+
+ return;
+ }
+
+ if (serialization.Serializer.NullValueHandling.GetValueOrDefault(NullValueHandling.Ignore) == NullValueHandling.Ignore)
+ {
+ return;
+ }
+
+ WritePropertyName(name);
+ WriteNull();
return;
}
diff --git a/src/global.json b/src/global.json
index 745718c26..e69a6eefb 100644
--- a/src/global.json
+++ b/src/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "9.0.100-rc.2.24474.11",
+ "version": "9.0.100",
"allowPrerelease": true,
"rollForward": "latestFeature"
}
diff --git a/usages/global.json b/usages/global.json
index 745718c26..e69a6eefb 100644
--- a/usages/global.json
+++ b/usages/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "9.0.100-rc.2.24474.11",
+ "version": "9.0.100",
"allowPrerelease": true,
"rollForward": "latestFeature"
}