diff --git a/docs/dates.md b/docs/dates.md
index cf7cdb72b..adff2dbd6 100644
--- a/docs/dates.md
+++ b/docs/dates.md
@@ -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
diff --git a/docs/guids.md b/docs/guids.md
index 2a3d9e87b..503f9cde1 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,13 +79,15 @@ await Verify(target)
```cs
VerifierSettings.DontScrubGuids();
```
-snippet source | anchor
+snippet source | anchor
## Inline Guids
-Strings containing inline Guids can also be scrubbed. To enable this behavior, use:
+Strings containing inline Guids can also be scrubbed. Guids in the `D` format (`00000000-0000-0000-0000-000000000000`) and the `N` format (`00000000000000000000000000000000`) are matched when bounded by non-alphanumeric characters. `B` and `P` formatted Guids are covered by the `D` format matching between their delimiters. Note that any 32 character hex sequence is a valid `N` format Guid, so hex content of that exact length (an MD5 hash for example) will also be scrubbed.
+
+To enable this behavior, use:
### Instance
@@ -103,7 +105,7 @@ public Task ScrubInlineGuidsInstance()
settings);
}
```
-snippet source | anchor
+snippet source | anchor
@@ -117,7 +119,7 @@ public Task ScrubInlineGuidsFluent() =>
Verify("content 651ad409-fc30-4b12-a47e-616d3f953e4c content")
.ScrubInlineGuids();
```
-snippet source | anchor
+snippet source | anchor
@@ -133,7 +135,7 @@ public static class ModuleInitializer
VerifierSettings.ScrubInlineGuids();
}
```
-snippet source | anchor
+snippet source | anchor
@@ -161,7 +163,7 @@ public Task NamedGuidInstance()
settings);
}
```
-snippet source | anchor
+snippet source | anchor
@@ -182,7 +184,7 @@ public Task NamedGuidFluent()
.AddNamedGuid(guid, "instanceNamed");
}
```
-snippet source | anchor
+snippet source | anchor
@@ -217,7 +219,7 @@ public Task InferredNamedGuidFluent()
.AddNamedGuid(namedGuid);
}
```
-snippet source | anchor
+snippet source | anchor
Result:
diff --git a/docs/mdsource/guids.source.md b/docs/mdsource/guids.source.md
index 6eb0f5e1a..a8d6127b4 100644
--- a/docs/mdsource/guids.source.md
+++ b/docs/mdsource/guids.source.md
@@ -31,7 +31,9 @@ snippet: DontScrubGuidsGlobal
## Inline Guids
-Strings containing inline Guids can also be scrubbed. To enable this behavior, use:
+Strings containing inline Guids can also be scrubbed. Guids in the `D` format (`00000000-0000-0000-0000-000000000000`) and the `N` format (`00000000000000000000000000000000`) are matched when bounded by non-alphanumeric characters. `B` and `P` formatted Guids are covered by the `D` format matching between their delimiters. Note that any 32 character hex sequence is a valid `N` format Guid, so hex content of that exact length (an MD5 hash for example) will also be scrubbed.
+
+To enable this behavior, use:
### Instance
diff --git a/docs/members-throw.md b/docs/members-throw.md
index fea107e64..7dbebe855 100644
--- a/docs/members-throw.md
+++ b/docs/members-throw.md
@@ -35,7 +35,7 @@ public Task CustomExceptionPropFluent()
.IgnoreMembersThatThrow();
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -45,7 +45,7 @@ Or globally:
```cs
VerifierSettings.IgnoreMembersThatThrow();
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -82,7 +82,7 @@ public Task ExceptionMessagePropFluent()
.IgnoreMembersThatThrow(_ => _.Message == "Ignore");
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -92,7 +92,7 @@ Or globally:
```cs
VerifierSettings.IgnoreMembersThatThrow(_ => _.Message == "Ignore");
```
-snippet source | anchor
+snippet source | anchor
Result:
diff --git a/docs/named-tuples.md b/docs/named-tuples.md
index cbc2a40f2..221a4f5ad 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/obsolete-members.md b/docs/obsolete-members.md
index 9a8412f1a..726f461d9 100644
--- a/docs/obsolete-members.md
+++ b/docs/obsolete-members.md
@@ -31,7 +31,7 @@ public Task WithObsoleteProp()
return Verify(target);
}
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -79,7 +79,7 @@ public Task WithObsoletePropIncludedFluent()
.IncludeObsoletes();
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -89,7 +89,7 @@ Or globally:
```cs
VerifierSettings.IncludeObsoletes();
```
-snippet source | anchor
+snippet source | anchor
Result:
diff --git a/docs/scrubbers.md b/docs/scrubbers.md
index ccbd5d869..3a3473b56 100644
--- a/docs/scrubbers.md
+++ b/docs/scrubbers.md
@@ -44,7 +44,7 @@ verifySettings.ScrubWindow(
return null;
});
```
-snippet source | anchor
+snippet source | anchor
`ScrubLines` and `ScrubLinesWithReplace` also accept span based delegates (`LineMatch` / `LineReplace`) that avoid allocating a string per line. Use an explicitly typed lambda parameter to select them, e.g. `ScrubLines((ReadOnlySpan line) => ...)`; untyped lambdas bind the string overloads.
@@ -69,7 +69,7 @@ Instead of being executed by the engine, `AddScrubber(Action)` mu
```cs
verifySettings.AddScrubber(_ => _.Remove(0, 100));
```
-snippet source | anchor
+snippet source | anchor
Since these run after every engine scrubber, they can also modify text that the engine has already replaced.
@@ -118,7 +118,7 @@ For example remove lines containing `text`:
```cs
verifySettings.ScrubLines(line => line.Contains("text"));
```
-snippet source | anchor
+snippet source | anchor
@@ -133,7 +133,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`).
@@ -145,7 +145,7 @@ Case insensitive by default (`StringComparison.OrdinalIgnoreCase`).
```cs
verifySettings.ScrubLinesContaining(StringComparison.Ordinal, "text1", "text2");
```
-snippet source | anchor
+snippet source | anchor
@@ -160,7 +160,7 @@ For example converts lines to upper case:
```cs
verifySettings.ScrubLinesWithReplace(line => line.ToUpper());
```
-snippet source | anchor
+snippet source | anchor
@@ -173,7 +173,7 @@ Replaces `Environment.MachineName` with `TheMachineName`.
```cs
verifySettings.ScrubMachineName();
```
-snippet source | anchor
+snippet source | anchor
@@ -186,7 +186,7 @@ Replaces `Environment.UserName` with `TheUserName`.
```cs
verifySettings.ScrubUserName();
```
-snippet source | anchor
+snippet source | anchor
@@ -788,7 +788,7 @@ Scrubbers can be scoped to verified files with a matching extension by passing t
```cs
verifySettings.ScrubReplace("json", "abc", "xyz");
```
-snippet source | anchor
+snippet source | anchor
A scrubber registered this way runs only for verified files with that extension, while a scrubber registered without an extension runs for all of them. Extension scoping is available at every [level](#Scrubber-levels), and for the legacy `AddScrubber(Action)` overloads.
diff --git a/docs/serializer-settings.md b/docs/serializer-settings.md
index f7cda568a..794480e4a 100644
--- a/docs/serializer-settings.md
+++ b/docs/serializer-settings.md
@@ -204,7 +204,7 @@ To disable this behavior globally use:
```cs
VerifierSettings.DontIgnoreEmptyCollections();
```
-snippet source | anchor
+snippet source | anchor
@@ -495,7 +495,7 @@ public Task ScopedSerializerFluent()
.AddExtraSettings(_ => _.TypeNameHandling = TypeNameHandling.All);
}
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -623,7 +623,7 @@ public Task IgnoreTypeFluent()
.IgnoreMembersWithType();
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -633,7 +633,7 @@ Or globally:
```cs
VerifierSettings.IgnoreMembersWithType();
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -770,7 +770,7 @@ public Task ScrubTypeFluent()
.ScrubMembersWithType();
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -780,7 +780,7 @@ Or globally:
```cs
VerifierSettings.ScrubMembersWithType();
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -859,7 +859,7 @@ public Task AddIgnoreInstanceFluent()
.IgnoreInstance(_ => _.Property == "Ignore");
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -869,7 +869,7 @@ Or globally:
```cs
VerifierSettings.IgnoreInstance(_ => _.Property == "Ignore");
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -931,7 +931,7 @@ public Task AddScrubInstanceFluent()
.ScrubInstance(_ => _.Property == "Ignore");
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -941,7 +941,7 @@ Or globally:
```cs
VerifierSettings.ScrubInstance(_ => _.Property == "Ignore");
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1004,7 +1004,7 @@ public Task IgnoreMemberByExpressionFluent()
_ => _.PropertyThatThrows);
}
```
-snippet source | anchor
+snippet source | anchor
Or globally
@@ -1019,7 +1019,7 @@ VerifierSettings.IgnoreMembers(
_ => _.GetOnlyProperty,
_ => _.PropertyThatThrows);
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1079,7 +1079,7 @@ public Task ScrubMemberByExpressionFluent()
_ => _.PropertyThatThrows);
}
```
-snippet source | anchor
+snippet source | anchor
Or globally
@@ -1094,7 +1094,7 @@ VerifierSettings.ScrubMembers(
_ => _.GetOnlyProperty,
_ => _.PropertyThatThrows);
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1173,7 +1173,7 @@ public Task IgnoreMemberByNameFluent()
.IgnoreMember(_ => _.PropertyThatThrows);
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -1193,7 +1193,7 @@ VerifierSettings.IgnoreMember("Field");
// For a specific type with expression
VerifierSettings.IgnoreMember(_ => _.PropertyThatThrows);
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1268,7 +1268,7 @@ public Task ScrubMemberByNameFluent()
.ScrubMember(_ => _.PropertyThatThrows);
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -1288,7 +1288,7 @@ VerifierSettings.ScrubMember("Field");
// For a specific type with expression
VerifierSettings.ScrubMember(_ => _.PropertyThatThrows);
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1381,7 +1381,7 @@ public Task IgnoreDictionaryByPredicate()
return Verify(target, settings);
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -1393,7 +1393,7 @@ VerifierSettings.IgnoreMembers(
_=>_.DeclaringType == typeof(TargetClass) &&
_.Name == "Proprty");
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1482,7 +1482,7 @@ public Task ScrubDictionaryByPredicate()
return Verify(target, settings);
}
```
-snippet source | anchor
+snippet source | anchor
Or globally:
@@ -1494,7 +1494,7 @@ VerifierSettings.ScrubMembers(
_=>_.DeclaringType == typeof(TargetClass) &&
_.Name == "Proprty");
```
-snippet source | anchor
+snippet source | anchor
Result:
@@ -1548,7 +1548,7 @@ public Task MemberConverterByExpression()
return Verify(input);
}
```
-snippet source | anchor
+snippet source | anchor
diff --git a/src/StrictJsonTests/SerializationTests.ScrubInlineGuidsNFormatInString.verified.txt b/src/StrictJsonTests/SerializationTests.ScrubInlineGuidsNFormatInString.verified.txt
new file mode 100644
index 000000000..92305f785
--- /dev/null
+++ b/src/StrictJsonTests/SerializationTests.ScrubInlineGuidsNFormatInString.verified.txt
@@ -0,0 +1 @@
+The string Guid_1
\ No newline at end of file
diff --git a/src/Verify.Tests/GuidScrubberTests.InlineNamedGuidNFormat.verified.txt b/src/Verify.Tests/GuidScrubberTests.InlineNamedGuidNFormat.verified.txt
new file mode 100644
index 000000000..20362a0e5
--- /dev/null
+++ b/src/Verify.Tests/GuidScrubberTests.InlineNamedGuidNFormat.verified.txt
@@ -0,0 +1 @@
+value: guidName
\ No newline at end of file
diff --git a/src/Verify.Tests/GuidScrubberTests.Run_n-d-same.verified.txt b/src/Verify.Tests/GuidScrubberTests.Run_n-d-same.verified.txt
new file mode 100644
index 000000000..d629666f8
--- /dev/null
+++ b/src/Verify.Tests/GuidScrubberTests.Run_n-d-same.verified.txt
@@ -0,0 +1 @@
+Guid_1 Guid_1
\ No newline at end of file
diff --git a/src/Verify.Tests/GuidScrubberTests.Run_n-dash.verified.txt b/src/Verify.Tests/GuidScrubberTests.Run_n-dash.verified.txt
new file mode 100644
index 000000000..95d007458
--- /dev/null
+++ b/src/Verify.Tests/GuidScrubberTests.Run_n-dash.verified.txt
@@ -0,0 +1 @@
+-Guid_1-
\ No newline at end of file
diff --git a/src/Verify.Tests/GuidScrubberTests.Run_n-duplicate.verified.txt b/src/Verify.Tests/GuidScrubberTests.Run_n-duplicate.verified.txt
new file mode 100644
index 000000000..d629666f8
--- /dev/null
+++ b/src/Verify.Tests/GuidScrubberTests.Run_n-duplicate.verified.txt
@@ -0,0 +1 @@
+Guid_1 Guid_1
\ No newline at end of file
diff --git a/src/Verify.Tests/GuidScrubberTests.Run_n-end-letters.verified.txt b/src/Verify.Tests/GuidScrubberTests.Run_n-end-letters.verified.txt
new file mode 100644
index 000000000..78fc3df3c
--- /dev/null
+++ b/src/Verify.Tests/GuidScrubberTests.Run_n-end-letters.verified.txt
@@ -0,0 +1 @@
+173535ae995b4cc6a74e8cd4be57039ca
\ No newline at end of file
diff --git a/src/Verify.Tests/GuidScrubberTests.Run_n-letters.verified.txt b/src/Verify.Tests/GuidScrubberTests.Run_n-letters.verified.txt
new file mode 100644
index 000000000..4335afcf6
--- /dev/null
+++ b/src/Verify.Tests/GuidScrubberTests.Run_n-letters.verified.txt
@@ -0,0 +1 @@
+a173535ae995b4cc6a74e8cd4be57039ca
\ No newline at end of file
diff --git a/src/Verify.Tests/GuidScrubberTests.Run_n-multiple.verified.txt b/src/Verify.Tests/GuidScrubberTests.Run_n-multiple.verified.txt
new file mode 100644
index 000000000..1e289258d
--- /dev/null
+++ b/src/Verify.Tests/GuidScrubberTests.Run_n-multiple.verified.txt
@@ -0,0 +1 @@
+Guid_1 Guid_2
\ No newline at end of file
diff --git a/src/Verify.Tests/GuidScrubberTests.Run_n-sha1.verified.txt b/src/Verify.Tests/GuidScrubberTests.Run_n-sha1.verified.txt
new file mode 100644
index 000000000..012818aef
--- /dev/null
+++ b/src/Verify.Tests/GuidScrubberTests.Run_n-sha1.verified.txt
@@ -0,0 +1 @@
+da39a3ee5e6b4b0d3255bfef95601890afd80709
\ No newline at end of file
diff --git a/src/Verify.Tests/GuidScrubberTests.Run_n-sha256.verified.txt b/src/Verify.Tests/GuidScrubberTests.Run_n-sha256.verified.txt
new file mode 100644
index 000000000..0dec1a2bd
--- /dev/null
+++ b/src/Verify.Tests/GuidScrubberTests.Run_n-sha256.verified.txt
@@ -0,0 +1 @@
+e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
\ No newline at end of file
diff --git a/src/Verify.Tests/GuidScrubberTests.Run_n-square.verified.txt b/src/Verify.Tests/GuidScrubberTests.Run_n-square.verified.txt
new file mode 100644
index 000000000..0ec11b6d8
--- /dev/null
+++ b/src/Verify.Tests/GuidScrubberTests.Run_n-square.verified.txt
@@ -0,0 +1 @@
+[Guid_1]
\ No newline at end of file
diff --git a/src/Verify.Tests/GuidScrubberTests.Run_n-start-letters.verified.txt b/src/Verify.Tests/GuidScrubberTests.Run_n-start-letters.verified.txt
new file mode 100644
index 000000000..0be9f08eb
--- /dev/null
+++ b/src/Verify.Tests/GuidScrubberTests.Run_n-start-letters.verified.txt
@@ -0,0 +1 @@
+a173535ae995b4cc6a74e8cd4be57039c
\ No newline at end of file
diff --git a/src/Verify.Tests/GuidScrubberTests.Run_n-upper.verified.txt b/src/Verify.Tests/GuidScrubberTests.Run_n-upper.verified.txt
new file mode 100644
index 000000000..bc34cb3ff
--- /dev/null
+++ b/src/Verify.Tests/GuidScrubberTests.Run_n-upper.verified.txt
@@ -0,0 +1 @@
+Guid_1
\ No newline at end of file
diff --git a/src/Verify.Tests/GuidScrubberTests.Run_n-zeros.verified.txt b/src/Verify.Tests/GuidScrubberTests.Run_n-zeros.verified.txt
new file mode 100644
index 000000000..3ea1b9dc9
--- /dev/null
+++ b/src/Verify.Tests/GuidScrubberTests.Run_n-zeros.verified.txt
@@ -0,0 +1 @@
+Guid_Empty
\ No newline at end of file
diff --git a/src/Verify.Tests/GuidScrubberTests.Run_n.verified.txt b/src/Verify.Tests/GuidScrubberTests.Run_n.verified.txt
new file mode 100644
index 000000000..bc34cb3ff
--- /dev/null
+++ b/src/Verify.Tests/GuidScrubberTests.Run_n.verified.txt
@@ -0,0 +1 @@
+Guid_1
\ No newline at end of file
diff --git a/src/Verify.Tests/GuidScrubberTests.cs b/src/Verify.Tests/GuidScrubberTests.cs
index 3c179b8da..ac83d2b95 100644
--- a/src/Verify.Tests/GuidScrubberTests.cs
+++ b/src/Verify.Tests/GuidScrubberTests.cs
@@ -11,7 +11,7 @@ public class GuidScrubberTests
static string ReplaceGuids(string value, Counter counter)
{
- var set = EngineScrubberSet.ForScrubbers([GuidMatcher.Instance]);
+ var set = EngineScrubberSet.ForScrubbers([GuidMatcher.Instance, GuidMatcher.NInstance]);
return ScrubEngine.Run(value, set, counter, emptyContext, applyDirectoryReplacements: false);
}
@@ -48,6 +48,19 @@ static string ReplaceGuids(string value, Counter counter)
[InlineData("1173535ae-995b-4cc6-a74e-8cd4be57039c1", "numbers")]
[InlineData("1173535ae-995b-4cc6-a74e-8cd4be57039c", "start-numbers")]
[InlineData("173535ae-995b-4cc6-a74e-8cd4be57039c1", "end-numbers")]
+ [InlineData("173535ae995b4cc6a74e8cd4be57039c", "n")]
+ [InlineData("173535ae995b4cc6a74e8cd4be57039c 173535ae995b4cc6a74e8cd4be57039d", "n-multiple")]
+ [InlineData("173535ae995b4cc6a74e8cd4be57039c 173535ae995b4cc6a74e8cd4be57039c", "n-duplicate")]
+ [InlineData("173535ae-995b-4cc6-a74e-8cd4be57039c 173535ae995b4cc6a74e8cd4be57039c", "n-d-same")]
+ [InlineData("173535AE995B4CC6A74E8CD4BE57039C", "n-upper")]
+ [InlineData("[173535ae995b4cc6a74e8cd4be57039c]", "n-square")]
+ [InlineData("-173535ae995b4cc6a74e8cd4be57039c-", "n-dash")]
+ [InlineData("a173535ae995b4cc6a74e8cd4be57039ca", "n-letters")]
+ [InlineData("a173535ae995b4cc6a74e8cd4be57039c", "n-start-letters")]
+ [InlineData("173535ae995b4cc6a74e8cd4be57039ca", "n-end-letters")]
+ [InlineData("00000000000000000000000000000000", "n-zeros")]
+ [InlineData("da39a3ee5e6b4b0d3255bfef95601890afd80709", "n-sha1")]
+ [InlineData("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "n-sha256")]
public async Task Run(string guid, string name)
{
using var counter = Counter.Start();
@@ -105,6 +118,11 @@ public void Multiple()
Assert.Equal("[Guid_1][Guid_2]", result);
}
+ [Fact]
+ public Task InlineNamedGuidNFormat() =>
+ Verify("value: c8eeaf99d5c4434185434597c3fd40c9")
+ .ScrubInlineGuids();
+
#region NamedGuidFluent
[Fact]
diff --git a/src/Verify.Tests/NewLineTests.TrailingNewlinesRaw.verified.txt b/src/Verify.Tests/NewLineTests.TrailingNewlinesRaw.verified.txt
new file mode 100644
index 000000000..7a2a9ee4f
--- /dev/null
+++ b/src/Verify.Tests/NewLineTests.TrailingNewlinesRaw.verified.txt
@@ -0,0 +1 @@
+a
diff --git a/src/Verify.Tests/Serialization/SerializationTests.ScrubInlineGuidsNFormatInString.verified.txt b/src/Verify.Tests/Serialization/SerializationTests.ScrubInlineGuidsNFormatInString.verified.txt
new file mode 100644
index 000000000..92305f785
--- /dev/null
+++ b/src/Verify.Tests/Serialization/SerializationTests.ScrubInlineGuidsNFormatInString.verified.txt
@@ -0,0 +1 @@
+The string Guid_1
\ No newline at end of file
diff --git a/src/Verify.Tests/Serialization/SerializationTests.cs b/src/Verify.Tests/Serialization/SerializationTests.cs
index 8a624fd50..27cb3ac82 100644
--- a/src/Verify.Tests/Serialization/SerializationTests.cs
+++ b/src/Verify.Tests/Serialization/SerializationTests.cs
@@ -1498,6 +1498,14 @@ public Task ScrubInlineGuidsInString()
.ScrubInlineGuids();
}
+ [Fact]
+ public Task ScrubInlineGuidsNFormatInString()
+ {
+ var id = Guid.NewGuid();
+ return Verify($"The string {id:N} ")
+ .ScrubInlineGuids();
+ }
+
[Fact]
public Task WriteRawInConverterTest()
{
diff --git a/src/Verify/Serialization/Scrubbers/GuidMatcher.cs b/src/Verify/Serialization/Scrubbers/GuidMatcher.cs
index a5f9b2c9a..68853261a 100644
--- a/src/Verify/Serialization/Scrubbers/GuidMatcher.cs
+++ b/src/Verify/Serialization/Scrubbers/GuidMatcher.cs
@@ -1,6 +1,9 @@
-// The inline guid scrubber: a fixed 36 char window over the canonical "D" format.
-// The engine anchor jumps between '-' chars at offset 8 (the first dash of the "D"
-// format), so no-match text is scanned vectorized instead of per position.
+// The inline guid scrubbers: a fixed 36 char window over the canonical "D" format
+// and a fixed 32 char window over the "N" format.
+// The "D" engine anchor jumps between '-' chars at offset 8 (the first dash of the
+// "D" format), so no-match text is scanned vectorized instead of per position.
+// "B" and "P" occurrences are covered by the "D" window matching between their
+// delimiters. "X" is not matched: its hex components are too short to reach a window.
static class GuidMatcher
{
public static readonly Scrubber Instance = Scrubber.GatedWindow(
@@ -13,6 +16,16 @@ static class GuidMatcher
anchorChar: '-',
anchorOffset: 8);
+ // No char appears at a fixed offset in the "N" format, so no anchor applies.
+ // Candidate positions are filtered by the engine's word boundary check, then by
+ // the first and last char prefilter, before the parse runs.
+ public static readonly Scrubber NInstance = Scrubber.GatedWindow(
+ 32,
+ 32,
+ MatchN,
+ static counter => counter.ScrubGuids,
+ requireWordBoundary: true);
+
static string? Match(CharSpan window, Counter counter, IReadOnlyDictionary context)
{
// Cheap prefilter: the "D" format has dashes at fixed offsets
@@ -31,4 +44,26 @@ static class GuidMatcher
return counter.Convert(guid);
}
+
+ static string? MatchN(CharSpan window, Counter counter, IReadOnlyDictionary context)
+ {
+ if (!IsHex(window[0]) ||
+ !IsHex(window[31]))
+ {
+ return null;
+ }
+
+ if (!Guid.TryParseExact(window, "N", out var guid))
+ {
+ return null;
+ }
+
+ return counter.Convert(guid);
+ }
+
+ static bool IsHex(char value) =>
+ value
+ is >= '0' and <= '9'
+ or >= 'a' and <= 'f'
+ or >= 'A' and <= 'F';
}
diff --git a/src/Verify/Serialization/Scrubbers/VerifierSettings_ExtensionMappedGlobalScrubbers.cs b/src/Verify/Serialization/Scrubbers/VerifierSettings_ExtensionMappedGlobalScrubbers.cs
index 60085999e..36edbd50b 100644
--- a/src/Verify/Serialization/Scrubbers/VerifierSettings_ExtensionMappedGlobalScrubbers.cs
+++ b/src/Verify/Serialization/Scrubbers/VerifierSettings_ExtensionMappedGlobalScrubbers.cs
@@ -90,8 +90,11 @@ public static void ScrubEmptyLines(string extension) =>
///
/// Replace inline s with a placeholder.
///
- public static void ScrubInlineGuids(string extension) =>
+ public static void ScrubInlineGuids(string extension)
+ {
AddScrubber(extension, GuidMatcher.Instance);
+ AddScrubber(extension, GuidMatcher.NInstance);
+ }
///
/// Scrub lines with an optional replace.
diff --git a/src/Verify/Serialization/Scrubbers/VerifierSettings_GlobalScrubbers.cs b/src/Verify/Serialization/Scrubbers/VerifierSettings_GlobalScrubbers.cs
index ea66c5860..c26a5339a 100644
--- a/src/Verify/Serialization/Scrubbers/VerifierSettings_GlobalScrubbers.cs
+++ b/src/Verify/Serialization/Scrubbers/VerifierSettings_GlobalScrubbers.cs
@@ -127,8 +127,11 @@ public static void ScrubInlineDates(
///
/// Replace inline s with a placeholder.
///
- public static void ScrubInlineGuids() =>
+ public static void ScrubInlineGuids()
+ {
AddScrubber(GuidMatcher.Instance);
+ AddScrubber(GuidMatcher.NInstance);
+ }
///
/// Scrub lines with an optional replace.
diff --git a/src/Verify/Serialization/Scrubbers/VerifySettings_ExtensionMappedInstanceScrubbers.cs b/src/Verify/Serialization/Scrubbers/VerifySettings_ExtensionMappedInstanceScrubbers.cs
index 199a20841..d31d9cb3a 100644
--- a/src/Verify/Serialization/Scrubbers/VerifySettings_ExtensionMappedInstanceScrubbers.cs
+++ b/src/Verify/Serialization/Scrubbers/VerifySettings_ExtensionMappedInstanceScrubbers.cs
@@ -78,8 +78,11 @@ public void ScrubLinesContaining(string extension, StringComparison comparison,
///
/// Replace inline s with a placeholder.
///
- public void ScrubInlineGuids(string extension) =>
+ public void ScrubInlineGuids(string extension)
+ {
AddScrubber(extension, GuidMatcher.Instance);
+ AddScrubber(extension, GuidMatcher.NInstance);
+ }
///
/// Remove any lines matching from the test results.
diff --git a/src/Verify/Serialization/Scrubbers/VerifySettings_InstanceScrubbers.cs b/src/Verify/Serialization/Scrubbers/VerifySettings_InstanceScrubbers.cs
index 281a099fa..04cebe482 100644
--- a/src/Verify/Serialization/Scrubbers/VerifySettings_InstanceScrubbers.cs
+++ b/src/Verify/Serialization/Scrubbers/VerifySettings_InstanceScrubbers.cs
@@ -93,6 +93,7 @@ public void ScrubInlineGuids()
}
AddScrubber(GuidMatcher.Instance);
+ AddScrubber(GuidMatcher.NInstance);
}
///