public async Task Count_ReturnsExpectedCount(RegexEngine engine, string pattern, string input, RegexOptions options, int expectedCount) { Regex r = await RegexHelpers.GetRegexAsync(engine, pattern, options); Assert.Equal(expectedCount, r.Count(input)); Assert.Equal(expectedCount, r.Count(input.AsSpan())); Assert.Equal(r.Count(input), r.Matches(input).Count); Assert.Equal(r.Count(input.AsSpan()), r.Matches(input).Count); if (options == RegexOptions.None && engine == RegexEngine.Interpreter) { Assert.Equal(expectedCount, Regex.Count(input, pattern)); Assert.Equal(expectedCount, Regex.Count(input.AsSpan(), pattern)); } switch (engine) { case RegexEngine.Interpreter: case RegexEngine.Compiled: case RegexEngine.NonBacktracking: RegexOptions engineOptions = RegexHelpers.OptionsFromEngine(engine); Assert.Equal(expectedCount, Regex.Count(input, pattern, options | engineOptions)); Assert.Equal(expectedCount, Regex.Count(input.AsSpan(), pattern, options | engineOptions)); Assert.Equal(expectedCount, Regex.Count(input, pattern, options | engineOptions, Regex.InfiniteMatchTimeout)); Assert.Equal(expectedCount, Regex.Count(input.AsSpan(), pattern, options | engineOptions, Regex.InfiniteMatchTimeout)); break; } }
public void EnumerateMatches_ReturnsExpectedCount(RegexEngine engine, string pattern, string input, int startat, RegexOptions options, int expectedCount) { Regex r = RegexHelpers.GetRegexAsync(engine, pattern, options).GetAwaiter().GetResult(); int count; count = 0; foreach (ValueMatch _ in r.EnumerateMatches(input, startat)) { count++; } Assert.Equal(expectedCount, count); bool isDefaultStartAt = startat == ((options & RegexOptions.RightToLeft) != 0 ? input.Length : 0); if (!isDefaultStartAt) { return; } if (options == RegexOptions.None && engine == RegexEngine.Interpreter) { count = 0; foreach (ValueMatch _ in Regex.EnumerateMatches(input, pattern)) { count++; } Assert.Equal(expectedCount, count); } switch (engine) { case RegexEngine.Interpreter: case RegexEngine.Compiled: case RegexEngine.NonBacktracking: RegexOptions engineOptions = RegexHelpers.OptionsFromEngine(engine); count = 0; foreach (ValueMatch _ in Regex.EnumerateMatches(input, pattern, options | engineOptions)) { count++; } Assert.Equal(expectedCount, count); count = 0; foreach (ValueMatch _ in Regex.EnumerateMatches(input, pattern, options | engineOptions, Regex.InfiniteMatchTimeout)) { count++; } Assert.Equal(expectedCount, count); break; } }
public async Task Count_ReturnsExpectedCount(RegexEngine engine, string pattern, string input, int startat, RegexOptions options, int expectedCount) { Regex r = await RegexHelpers.GetRegexAsync(engine, pattern, options); Assert.Equal(expectedCount, r.Count(input.AsSpan(), startat)); Assert.Equal(r.Count(input.AsSpan(), startat), r.Matches(input, startat).Count); bool isDefaultStartAt = startat == ((options & RegexOptions.RightToLeft) != 0 ? input.Length : 0); if (!isDefaultStartAt) { return; } Assert.Equal(expectedCount, r.Count(input)); Assert.Equal(expectedCount, r.Count(input.AsSpan())); Assert.Equal(r.Count(input), r.Matches(input).Count); Assert.Equal(r.Count(input.AsSpan()), r.Matches(input).Count); if (options == RegexOptions.None && engine == RegexEngine.Interpreter) { Assert.Equal(expectedCount, Regex.Count(input, pattern)); Assert.Equal(expectedCount, Regex.Count(input.AsSpan(), pattern)); } switch (engine) { case RegexEngine.Interpreter: case RegexEngine.Compiled: case RegexEngine.NonBacktracking: RegexOptions engineOptions = RegexHelpers.OptionsFromEngine(engine); Assert.Equal(expectedCount, Regex.Count(input, pattern, options | engineOptions)); Assert.Equal(expectedCount, Regex.Count(input.AsSpan(), pattern, options | engineOptions)); Assert.Equal(expectedCount, Regex.Count(input, pattern, options | engineOptions, Regex.InfiniteMatchTimeout)); Assert.Equal(expectedCount, Regex.Count(input.AsSpan(), pattern, options | engineOptions, Regex.InfiniteMatchTimeout)); break; } }
public async Task Count_Timeout_ThrowsAfterTooLongExecution(RegexEngine engine) { if (RegexHelpers.IsNonBacktracking(engine)) { // Test relies on backtracking taking a long time return; } const string Pattern = @"^(\w+\s?)*$"; const string Input = "An input string that takes a very very very very very very very very very very very long time!"; Regex r = await RegexHelpers.GetRegexAsync(engine, Pattern, RegexOptions.None, TimeSpan.FromMilliseconds(1)); Stopwatch sw = Stopwatch.StartNew(); Assert.Throws <RegexMatchTimeoutException>(() => r.Count(Input)); Assert.Throws <RegexMatchTimeoutException>(() => r.Count(Input.AsSpan())); Assert.InRange(sw.Elapsed.TotalSeconds, 0, 10); // arbitrary upper bound that should be well above what's needed with a 1ms timeout switch (engine) { case RegexEngine.Interpreter: case RegexEngine.Compiled: sw = Stopwatch.StartNew(); Assert.Throws <RegexMatchTimeoutException>(() => Regex.Count(Input, Pattern, RegexHelpers.OptionsFromEngine(engine), TimeSpan.FromMilliseconds(1))); Assert.Throws <RegexMatchTimeoutException>(() => Regex.Count(Input.AsSpan(), Pattern, RegexHelpers.OptionsFromEngine(engine), TimeSpan.FromMilliseconds(1))); Assert.InRange(sw.Elapsed.TotalSeconds, 0, 10); // arbitrary upper bound that should be well above what's needed with a 1ms timeout break; } }