diff --git a/src/Verify.Tests/Naming/UseTextForParametersTests.cs b/src/Verify.Tests/Naming/UseTextForParametersTests.cs new file mode 100644 index 000000000..ea128f98d --- /dev/null +++ b/src/Verify.Tests/Naming/UseTextForParametersTests.cs @@ -0,0 +1,29 @@ +public class UseTextForParametersTests +{ + // The text is appended to the file name verbatim, so it has to be a valid file name. + // A `:` used to pass validation and then, on Windows, divert the received file into an + // NTFS alternate data stream, so no received file appeared at all. + [Theory] + [InlineData("ratio 16:9")] + [InlineData("a*b")] + [InlineData("a?b")] + [InlineData("a|b")] + // `#` is reserved for the indexed-target namespace + [InlineData("a#1")] + public void InvalidCharactersThrow(string text) + { + var settings = new VerifySettings(); + + var exception = Assert.Throws(() => settings.UseTextForParameters(text)); + Assert.Contains("Invalid character for file name", exception.Message); + } + + [Fact] + public void ValidTextIsAccepted() + { + var settings = new VerifySettings(); + settings.UseTextForParameters("ratio 16-9"); + + Assert.Equal("ratio 16-9", settings.parametersText); + } +} diff --git a/src/Verify/Guards.cs b/src/Verify/Guards.cs index 96cb8cbc3..d9a286e72 100644 --- a/src/Verify/Guards.cs +++ b/src/Verify/Guards.cs @@ -16,6 +16,18 @@ public static void BadFileName(string name, [CallerArgumentExpression("name")] s } } + public static void BadParametersText(string value, [CallerArgumentExpression(nameof(value))] string argumentName = "") + { + BadFileName(value, argumentName); + + // `#` starts the indexed-target namespace, so a value containing one would make + // this case's files look like the targets of another case. + if (value.Contains('#')) + { + throw new ArgumentException($"Invalid character for file name. Value: {value}. Char:#", argumentName); + } + } + static char[] invalidPathChars = Path .GetInvalidPathChars() .Concat(invalidFileChars.Except(['/', '\\', ':'])) diff --git a/src/Verify/VerifySettings.cs b/src/Verify/VerifySettings.cs index 8eaae309a..dce16fc8b 100644 --- a/src/Verify/VerifySettings.cs +++ b/src/Verify/VerifySettings.cs @@ -156,7 +156,12 @@ public VerifySettings() /// public void UseTextForParameters(string parametersText) { - Guards.AgainstBadExtension(parametersText); + // The text goes into the file name verbatim, so it is validated as a file name, + // the same as UseFileName, UseTypeName and UseMethodName. The extension guard + // used to be applied here, which let `:`, `*`, `?`, `"`, `<`, `>` and `|` through + // to fail at write time, or on Windows silently divert the received file into an + // NTFS alternate data stream. + Guards.BadParametersText(parametersText); if (parameters is not null) {