From c211ed686c330123b54b1730e631dbd29d9c8ff8 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Sun, 8 Aug 2021 17:52:29 -0600 Subject: [PATCH 1/7] Rust parser tests --- .../tests/RegexParserTests.cs | 87 ++++++++----------- .../tests/RegexParserTests.netcoreapp.cs | 73 ++++++++++++++-- .../tests/RegexParserTests.netfx.cs | 22 ++++- 3 files changed, 121 insertions(+), 61 deletions(-) diff --git a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.cs b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.cs index e4f555bbc0e89d..cd0972be6af5f2 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.cs @@ -565,21 +565,6 @@ public partial class RegexParserTests [InlineData(@"\bgr[ae]y\b", RegexOptions.None, null)] [InlineData(@"\b((?# case sensitive comparison)D\w+)\s(?ixn)((?#case insensitive comparison)d\w+)\b", RegexOptions.None, null)] [InlineData(@"\{\d+(,-*\d+)*(\:\w{1,4}?)*\}(?x) # Looks for a composite format item.", RegexOptions.None, null)] - public void Parse(string pattern, RegexOptions options, object errorObj, int offset = -1) - { - RegexParseError? error = (RegexParseError?)errorObj; - - Assert.True(error == null || offset > 0, "All tests must be given positive offsets, or null if no offset should be tested."); - - // Parse the main tree and if parsing fails check if the supplied error matches. - ParseTree(pattern, options, error, offset); - - // Assert that only ArgumentException might be thrown during parsing. - ParseSubTrees(pattern, options); - } - - [Theory] - // Negative tests [InlineData(@"cat([a-\d]*)dog", RegexOptions.None, RegexParseError.ShorthandClassInCharacterRange, 9)] [InlineData(@"\k<1", RegexOptions.None, RegexParseError.UnrecognizedEscape, 2)] [InlineData(@"(?')", RegexOptions.None, RegexParseError.CaptureGroupNameInvalid, 3)] @@ -716,67 +701,65 @@ public void Parse(string pattern, RegexOptions options, object errorObj, int off [InlineData("[a-z-[b][", RegexOptions.None, RegexParseError.UnterminatedBracket, 9)] [InlineData("(?()|||||)", RegexOptions.None, RegexParseError.AlternationHasTooManyConditions, 10)] [InlineData("[^]", RegexOptions.None, RegexParseError.UnterminatedBracket, 3)] - [InlineData("\\", RegexOptions.None, RegexParseError.UnescapedEndingBackslash, 1)] [InlineData("??", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 1)] [InlineData("(?=*)", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 4)] [InlineData("((((((*))))))", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 7)] - public void ParseCheckOffset(string pattern, RegexOptions options, object errorObj, int offset) + public void ParseCheckOffset(string pattern, RegexOptions options, object errorObj, int offset = -1) { - RegexParseError? error = (RegexParseError?)errorObj; - - // Parse the main tree and if parsing fails check if the supplied error matches. - ParseTree(pattern, options, error, offset); - - // Assert that only ArgumentException might be thrown during parsing. - ParseSubTrees(pattern, options); + Parse(pattern, options, errorObj, offset); } - - private static void ParseSubTrees(string pattern, RegexOptions options) + private static void Parse(string pattern, RegexOptions options, object errorObj, int offset = -1) { - // Trim the input from the right and make sure tree invariants hold - for (int i = pattern.Length - 1; i > 0; i--) - { - ParseSubTree(pattern.Substring(0, i), options); - } - - // Trim the input from the left and make sure tree invariants hold - for (int i = 1; i < pattern.Length; i++) - { - ParseSubTree(pattern.Substring(i), options); - } - - // Skip middles - for (int i = 1; i < pattern.Length; i++) - { - ParseSubTree(pattern.Substring(0, i) + pattern.Substring(i + 1), options); - } - } + RegexParseError? error = (RegexParseError?)errorObj; - static void ParseTree(string pattern, RegexOptions options, RegexParseError? error, int offset) - { if (error != null) { + Assert.True(error.Value >= 0); Throws(error.Value, offset, () => new Regex(pattern, options)); return; } + Assert.True(offset == -1); + // Nothing to assert here without having access to internals. - new Regex(pattern, options); + new Regex(pattern, options); // Does not throw + + ParsePatternFragments(pattern, options); } - private static void ParseSubTree(string pattern, RegexOptions options) + private static void ParsePatternFragments(string pattern, RegexOptions options) { - try + // Trim the input in various places and parse. + // Verify that if it throws, it's the correct exception type + for (int i = pattern.Length - 1; i > 0; i--) { - new Regex(pattern, options); + MayThrow(() => new Regex(pattern.Substring(0, i), options)); } - catch (ArgumentException) + + for (int i = 1; i < pattern.Length; i++) { - // We are fine with ArgumentExceptions being thrown during sub expression parsing. + MayThrow(() => new Regex(pattern.Substring(i), options)); + } + + for (int i = 1; i < pattern.Length; i++) + { + MayThrow(() => new Regex(pattern.Substring(0, i) + pattern.Substring(i + 1), options)); } } + /// + /// Checks that action throws either a RegexParseException or an ArgumentException depending on the + /// environment and the supplied error. + /// + /// The expected parse error + /// The action to invoke. static partial void Throws(RegexParseError error, int offset, Action action); + + /// + /// Checks that action succeeds or throws either a RegexParseException or an ArgumentException. + /// + /// The action to invoke. + static partial void MayThrow(Action action); } } diff --git a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs index 9e246688ea6f9e..790d6418417b9f 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs @@ -11,15 +11,11 @@ namespace System.Text.RegularExpressions.Tests public partial class RegexParserTests { [Theory] - [InlineData(@"[a-\-]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)] - [InlineData(@"[a-\-b]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)] - [InlineData(@"[a-\-\-b]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)] - [InlineData(@"[a-\-\D]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)] - [InlineData(@"[a-\-\-\D]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)] - [InlineData(@"[a -\-\b]", RegexOptions.None, null, 5)] - // OutOfMemoryException + + // Avoid OutOfMemoryException [InlineData("a{2147483647}", RegexOptions.None, null)] [InlineData("a{2147483647,}", RegexOptions.None, null)] + [InlineData(@"(?(?N))", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)] [InlineData(@"(?(?i))", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)] [InlineData(@"(?(?I))", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)] @@ -30,7 +26,6 @@ public partial class RegexParserTests [InlineData(@"(?(?X))", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)] [InlineData(@"(?(?n))", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)] [InlineData(@"(?(?m))", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)] - // IndexOutOfRangeException [InlineData("(?<-", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 3)] [InlineData("(?<-", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupingConstruct, 3)] [InlineData(@"^[^<>]*(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!))$", RegexOptions.None, null)] @@ -90,6 +85,48 @@ public partial class RegexParserTests [InlineData("a{0,2147483648}", RegexOptions.None, RegexParseError.QuantifierOrCaptureGroupOutOfRange, 14)] // Surrogate pair which is parsed as [char,char-char,char] as we operate on UTF-16 code units. [InlineData("[\uD82F\uDCA0-\uD82F\uDCA3]", RegexOptions.IgnoreCase, RegexParseError.ReversedCharacterRange, 5)] + + // Following are borrowed from Rust regex tests ============ + // https://github.com/rust-lang/regex/blob/master/tests/noparse.rs + [InlineData(@"*", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 1)] + [InlineData(@"[A-", RegexOptions.None, RegexParseError.UnterminatedBracket, 3)] + [InlineData(@"[A", RegexOptions.None, RegexParseError.UnterminatedBracket, 2)] + [InlineData(@"[\A]", RegexOptions.None, RegexParseError.UnrecognizedEscape, 3)] + [InlineData(@"[\z]", RegexOptions.None, RegexParseError.UnrecognizedEscape, 3)] + [InlineData(@"(", RegexOptions.None, RegexParseError.InsufficientClosingParentheses, 1)] + [InlineData(@")", RegexOptions.None, RegexParseError.InsufficientOpeningParentheses, 1)] + [InlineData(@"[a-Z]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 4)] + [InlineData(@"(?P<>a)", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 3)] + [InlineData(@"(?P)", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 3)] + [InlineData(@"(?a)a", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 3)] + [InlineData(@"a{2,1}", RegexOptions.None, RegexParseError.ReversedQuantifierRange, 6)] + [InlineData(@"(?", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 2)] + [InlineData(@"\8", RegexOptions.None, RegexParseError.UndefinedNumberedReference, 2)] + [InlineData(@"\xG0", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 3)] + [InlineData(@"\xF", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 2)] + [InlineData(@"\x{fffg}", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 3)] + [InlineData(@"(?a)", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 3)] + [InlineData(@"(?)", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 2)] + [InlineData(@"(?P.)(?P.)", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 3)] + [InlineData(@"[a-\A]", RegexOptions.None, RegexParseError.UnrecognizedEscape, 5)] + [InlineData(@"[a-\z]", RegexOptions.None, RegexParseError.UnrecognizedEscape, 5)] + [InlineData(@"[a-\b]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)] + [InlineData(@"[a-\-]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)] + [InlineData(@"[a-\-b]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)] + [InlineData(@"[a-\-\-b]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)] + [InlineData(@"[a-\-\D]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)] + [InlineData(@"[a-\-\-\D]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)] + [InlineData(@"[a -\-\b]", RegexOptions.None, null)] + [InlineData(@"[\b]", RegexOptions.None, null)] // errors in rust: class_no_boundary + [InlineData(@"a{10000000}", RegexOptions.None, null)] // errors in rust: too_big + [InlineData(@"a{1001", RegexOptions.None, null)] // errors in rust: counted_no_close + [InlineData(@"a{-1,1}", RegexOptions.None, null)] // errors in rust: counted_nonnegative + [InlineData(@"\\", RegexOptions.None, null)] // errors in rust: unfinished_escape + [InlineData(@"(?-i-i)", RegexOptions.None, null)] // errors in rust: double_neg + [InlineData(@"(?i-)", RegexOptions.None, null)] // errors in rust: neg_empty + [InlineData(@"[a-[:lower:]]", RegexOptions.None, null)] // errors in rust: range_end_no_class + // End of Rust parser tests ============== + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] public void Parse_Netcoreapp(string pattern, RegexOptions options, object error, int offset = -1) { @@ -146,5 +183,25 @@ static partial void Throws(RegexParseError error, int offset, Action action) throw new XunitException($"Expected RegexParseException with error: ({error}) -> Actual: No exception thrown"); } + + /// + /// Checks that action succeeds or throws either a RegexParseException or an ArgumentException. + /// + /// The action to invoke. + static partial void MayThrow(Action action) + { + try + { + action(); + } + catch (RegexParseException) + { + return; + } + catch (Exception e) + { + throw new XunitException($"Expected RegexParseException or no exception -> Actual: ({e})"); + } + } } } diff --git a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netfx.cs b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netfx.cs index 4e9006e8a130b5..5ac412de9b8aa0 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netfx.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netfx.cs @@ -11,7 +11,7 @@ namespace System.Text.RegularExpressions.Tests public partial class RegexParserTests { /// - /// Checks if action throws either a RegexParseException or an ArgumentException depending on the + /// Checks that action throws either a RegexParseException or an ArgumentException depending on the /// environment and the supplied error. /// /// The expected parse error @@ -34,5 +34,25 @@ static partial void Throws(RegexParseError error, int offset, Action action) throw new XunitException($"Expected ArgumentException with error: ({error}) -> Actual: No exception thrown"); } + + /// + /// Checks that action succeeds or throws either a RegexParseException or an ArgumentException. + /// + /// The action to invoke. + static partial void MayThrow(Action action) + { + try + { + action(); + } + catch (ArgumentException) + { + return; + } + catch (Exception e) + { + throw new XunitException($"Expected RegexParseException or no exception -> Actual: ({e})"); + } + } } } From 9637fc7d7e57074f2bb26a316cc9d26cd660413f Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Tue, 24 Aug 2021 10:48:24 -0600 Subject: [PATCH 2/7] Update msg --- .../tests/RegexParserTests.netcoreapp.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs index 790d6418417b9f..8196f08f8b3867 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs @@ -174,7 +174,7 @@ static partial void Throws(RegexParseError error, int offset, Action action) return; } - throw new XunitException($"Expected RegexParseException with error: ({error}) -> Actual error: {regexParseError})"); + throw new XunitException($"Expected RegexParseException with error {error} offset {offset} -> Actual error: {regexParseError} offset {e.Offset})"); } catch (Exception e) { From 1621d141319e391fa48aa88918b2faba1bbafe7e Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Tue, 24 Aug 2021 10:56:17 -0600 Subject: [PATCH 3/7] comment --- .../System.Text.RegularExpressions/tests/RegexParserTests.cs | 3 ++- .../tests/RegexParserTests.netcoreapp.cs | 3 ++- .../tests/RegexParserTests.netfx.cs | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.cs b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.cs index cd0972be6af5f2..d865e338527b16 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.cs @@ -757,7 +757,8 @@ private static void ParsePatternFragments(string pattern, RegexOptions options) static partial void Throws(RegexParseError error, int offset, Action action); /// - /// Checks that action succeeds or throws either a RegexParseException or an ArgumentException. + /// Checks that action succeeds or throws either a RegexParseException or an ArgumentException depending on the + // environment and the action. /// /// The action to invoke. static partial void MayThrow(Action action); diff --git a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs index 8196f08f8b3867..d1e8a3a6025f73 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs @@ -185,7 +185,8 @@ static partial void Throws(RegexParseError error, int offset, Action action) } /// - /// Checks that action succeeds or throws either a RegexParseException or an ArgumentException. + /// Checks that action succeeds or throws either a RegexParseException or an ArgumentException depending on the + // environment and the action. /// /// The action to invoke. static partial void MayThrow(Action action) diff --git a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netfx.cs b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netfx.cs index 5ac412de9b8aa0..9dc0905d2e1561 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netfx.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netfx.cs @@ -28,7 +28,7 @@ static partial void Throws(RegexParseError error, int offset, Action action) return; } catch (Exception e) - { + { throw new XunitException($"Expected ArgumentException -> Actual: {e}"); } @@ -36,7 +36,8 @@ static partial void Throws(RegexParseError error, int offset, Action action) } /// - /// Checks that action succeeds or throws either a RegexParseException or an ArgumentException. + /// Checks that action succeeds or throws either a RegexParseException or an ArgumentException depending on the + // environment and the action. /// /// The action to invoke. static partial void MayThrow(Action action) From 0b7474655672443643780829c684520763ff4781 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Wed, 25 Aug 2021 22:11:56 -0600 Subject: [PATCH 4/7] Work around #56945 --- .../System.IO.FileSystem/tests/File/EncryptDecrypt.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs index 984afef972bc41..12299fad33fcf5 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs @@ -43,9 +43,11 @@ public static void EncryptDecrypt_Read() { File.Encrypt(tmpFileName); } - catch (IOException e) when (e.HResult == unchecked((int)0x80070490)) + catch (IOException e) when (e.HResult == unchecked((int)0x80070490) || + (e.HResult == unchecked((int)0x80071776))) { // Ignore ERROR_NOT_FOUND 1168 (0x490). It is reported when EFS is disabled by domain policy. + // Ignore ERROR_NO_USER_KEYS (0x1776). This occurs when no user key exists to encrypt with. return; } From 8a76e2b5e117f8453646eba1781d85e12e089081 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Wed, 25 Aug 2021 22:17:04 -0600 Subject: [PATCH 5/7] Add license notice --- .../tests/THIRD-PARTY-NOTICES.TXT | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/libraries/System.Text.RegularExpressions/tests/THIRD-PARTY-NOTICES.TXT diff --git a/src/libraries/System.Text.RegularExpressions/tests/THIRD-PARTY-NOTICES.TXT b/src/libraries/System.Text.RegularExpressions/tests/THIRD-PARTY-NOTICES.TXT new file mode 100644 index 00000000000000..fc8f24d3542f64 --- /dev/null +++ b/src/libraries/System.Text.RegularExpressions/tests/THIRD-PARTY-NOTICES.TXT @@ -0,0 +1,38 @@ +.NET Runtime uses third-party libraries or other resources that may be +distributed under licenses different than the .NET Runtime software. + +In the event that we accidentally failed to list a required notice, please +bring it to our attention. Post an issue or email us: + + dotnet@microsoft.com + +The attached notices are provided for information only. + +License notice for rust-lang/regex +------------------------------- + +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file From 3253d533a0f5fc99856e07c497d2c015360e03e1 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Wed, 25 Aug 2021 22:18:57 -0600 Subject: [PATCH 6/7] Update url --- .../tests/THIRD-PARTY-NOTICES.TXT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Text.RegularExpressions/tests/THIRD-PARTY-NOTICES.TXT b/src/libraries/System.Text.RegularExpressions/tests/THIRD-PARTY-NOTICES.TXT index fc8f24d3542f64..8c51928cfb1e72 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/THIRD-PARTY-NOTICES.TXT +++ b/src/libraries/System.Text.RegularExpressions/tests/THIRD-PARTY-NOTICES.TXT @@ -8,7 +8,7 @@ bring it to our attention. Post an issue or email us: The attached notices are provided for information only. -License notice for rust-lang/regex +License notice for https://github.com/rust-lang/regex ------------------------------- Copyright (c) 2014 The Rust Project Developers From 0342fcd7e023df93d3c160459452305fbbe01519 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Mon, 30 Aug 2021 20:22:24 -0600 Subject: [PATCH 7/7] feedback --- .../tests/RegexParserTests.cs | 21 ++++++++++--------- .../tests/RegexParserTests.netcoreapp.cs | 12 ++--------- .../tests/RegexParserTests.netfx.cs | 12 ++--------- 3 files changed, 15 insertions(+), 30 deletions(-) diff --git a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.cs b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.cs index d865e338527b16..846fcbce60fa65 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.cs @@ -704,23 +704,21 @@ public partial class RegexParserTests [InlineData("??", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 1)] [InlineData("(?=*)", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 4)] [InlineData("((((((*))))))", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 7)] - public void ParseCheckOffset(string pattern, RegexOptions options, object errorObj, int offset = -1) + public void ParseCheckOffset(string pattern, RegexOptions options, RegexParseError? error, int offset = -1) { - Parse(pattern, options, errorObj, offset); + Parse(pattern, options, error, offset); } - private static void Parse(string pattern, RegexOptions options, object errorObj, int offset = -1) + private static void Parse(string pattern, RegexOptions options, RegexParseError? error, int offset = -1) { - RegexParseError? error = (RegexParseError?)errorObj; - if (error != null) { - Assert.True(error.Value >= 0); + Assert.InRange(offset, 0, int.MaxValue); Throws(error.Value, offset, () => new Regex(pattern, options)); return; } - Assert.True(offset == -1); + Assert.Equal(-1, offset); // Nothing to assert here without having access to internals. new Regex(pattern, options); // Does not throw @@ -734,17 +732,20 @@ private static void ParsePatternFragments(string pattern, RegexOptions options) // Verify that if it throws, it's the correct exception type for (int i = pattern.Length - 1; i > 0; i--) { - MayThrow(() => new Regex(pattern.Substring(0, i), options)); + string str = pattern.Substring(0, i); + MayThrow(() => new Regex(str, options)); } for (int i = 1; i < pattern.Length; i++) { - MayThrow(() => new Regex(pattern.Substring(i), options)); + string str = pattern.Substring(i); + MayThrow(() => new Regex(str, options)); } for (int i = 1; i < pattern.Length; i++) { - MayThrow(() => new Regex(pattern.Substring(0, i) + pattern.Substring(i + 1), options)); + string str = pattern.Substring(0, i) + pattern.Substring(i + 1); + MayThrow(() => new Regex(str, options)); } } diff --git a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs index d1e8a3a6025f73..cc1d5f8658fe9b 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs @@ -128,7 +128,7 @@ public partial class RegexParserTests // End of Rust parser tests ============== [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] - public void Parse_Netcoreapp(string pattern, RegexOptions options, object error, int offset = -1) + public void Parse_Netcoreapp(string pattern, RegexOptions options, RegexParseError? error, int offset = -1) { Parse(pattern, options, error, offset); } @@ -191,15 +191,7 @@ static partial void Throws(RegexParseError error, int offset, Action action) /// The action to invoke. static partial void MayThrow(Action action) { - try - { - action(); - } - catch (RegexParseException) - { - return; - } - catch (Exception e) + if (Record.Exception(action) is Exception e && e is not RegexParseException) { throw new XunitException($"Expected RegexParseException or no exception -> Actual: ({e})"); } diff --git a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netfx.cs b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netfx.cs index 9dc0905d2e1561..e70d29a8dd388f 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netfx.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netfx.cs @@ -42,17 +42,9 @@ static partial void Throws(RegexParseError error, int offset, Action action) /// The action to invoke. static partial void MayThrow(Action action) { - try - { - action(); - } - catch (ArgumentException) - { - return; - } - catch (Exception e) + if (Record.Exception(action) is Exception e && e is not ArgumentException) { - throw new XunitException($"Expected RegexParseException or no exception -> Actual: ({e})"); + throw new XunitException($"Expected ArgumentException or no exception -> Actual: ({e})"); } } }