mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-23 08:48:28 +02:00
GUID Pattern support in RegexMatcher (#699)
* Add the RegexGuid class * Use of RegexGuid in the RegexMatcher * Fix up the CodeFactor violations * Rename RegexGuid --> RegexExtended
This commit is contained in:
@@ -5,6 +5,7 @@ using AnyOfTypes;
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using WireMock.Extensions;
|
using WireMock.Extensions;
|
||||||
using WireMock.Models;
|
using WireMock.Models;
|
||||||
|
using WireMock.RegularExpressions;
|
||||||
using WireMock.Validation;
|
using WireMock.Validation;
|
||||||
|
|
||||||
namespace WireMock.Matchers
|
namespace WireMock.Matchers
|
||||||
@@ -17,7 +18,7 @@ namespace WireMock.Matchers
|
|||||||
public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||||
{
|
{
|
||||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||||
private readonly Regex[] _expressions;
|
private readonly RegexExtended[] _expressions;
|
||||||
|
|
||||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||||
public MatchBehaviour MatchBehaviour { get; }
|
public MatchBehaviour MatchBehaviour { get; }
|
||||||
@@ -76,7 +77,7 @@ namespace WireMock.Matchers
|
|||||||
options |= RegexOptions.IgnoreCase;
|
options |= RegexOptions.IgnoreCase;
|
||||||
}
|
}
|
||||||
|
|
||||||
_expressions = patterns.Select(p => new Regex(p.GetPattern(), options)).ToArray();
|
_expressions = patterns.Select(p => new RegexExtended(p.GetPattern(), options)).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||||
|
|||||||
72
src/WireMock.Net/RegularExpressions/RegexExtended.cs
Normal file
72
src/WireMock.Net/RegularExpressions/RegexExtended.cs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using WireMock.Validation;
|
||||||
|
|
||||||
|
namespace WireMock.RegularExpressions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Extension to the <see cref="Regex"/> object, adding support for GUID tokens for matching on.
|
||||||
|
/// </summary>
|
||||||
|
public class RegexExtended : Regex
|
||||||
|
{
|
||||||
|
/// <inheritdoc cref="Regex"/>
|
||||||
|
public RegexExtended(string pattern) : this(pattern, RegexOptions.None)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Regex"/>
|
||||||
|
public RegexExtended(string pattern,
|
||||||
|
RegexOptions options)
|
||||||
|
: this(pattern, options, Regex.InfiniteMatchTimeout)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Regex"/>
|
||||||
|
public RegexExtended(string pattern,
|
||||||
|
RegexOptions options,
|
||||||
|
TimeSpan matchTimeout)
|
||||||
|
: base(ReplaceGuidPattern(pattern), options, matchTimeout)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dictionary of various Guid tokens with a corresponding regular expression pattern to use instead.
|
||||||
|
private static readonly Dictionary<string, string> GuidTokenPatterns = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
// Lower case format `B` Guid pattern
|
||||||
|
{ @"\guidb", @"(\{[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\})" },
|
||||||
|
// Upper case format `B` Guid pattern
|
||||||
|
{ @"\GUIDB", @"(\{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}\})" },
|
||||||
|
// Lower case format `D` Guid pattern
|
||||||
|
{ @"\guidd", "([a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12})" },
|
||||||
|
// Upper case format `D` Guid pattern
|
||||||
|
{ @"\GUIDD", "([A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12})" },
|
||||||
|
// Lower case format `N` Guid pattern
|
||||||
|
{ @"\guidn", "([a-z0-9]{32})" },
|
||||||
|
// Upper case format `N` Guid pattern
|
||||||
|
{ @"\GUIDN", "([A-Z0-9]{32})" },
|
||||||
|
// Lower case format `P` Guid pattern
|
||||||
|
{ @"\guidp", @"(\([a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\))" },
|
||||||
|
// Upper case format `P` Guid pattern
|
||||||
|
{ @"\GUIDP", @"(\([A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}\))" },
|
||||||
|
// Lower case format `X` Guid pattern
|
||||||
|
{ @"\guidx", @"(\{0x[a-f0-9]{8},0x[a-f0-9]{4},0x[a-f0-9]{4},\{(0x[a-f0-9]{2},){7}(0x[a-f0-9]{2})\}\})" },
|
||||||
|
// Upper case format `X` Guid pattern
|
||||||
|
{ @"\GUIDX", @"(\{0x[A-F0-9]{8},0x[A-F0-9]{4},0x[A-F0-9]{4},\{(0x[A-F0-9]{2},){7}(0x[A-F0-9]{2})\}\})" },
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Replaces all instances of valid GUID tokens with the correct regular expression to match.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pattern">Pattern to replace token for.</param>
|
||||||
|
private static string ReplaceGuidPattern(string pattern)
|
||||||
|
{
|
||||||
|
Check.NotNull(pattern, nameof(pattern));
|
||||||
|
foreach (var tokenPattern in GuidTokenPatterns)
|
||||||
|
{
|
||||||
|
pattern = pattern.Replace(tokenPattern.Key, tokenPattern.Value);
|
||||||
|
}
|
||||||
|
return pattern;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
100
test/WireMock.Net.Tests/RegularExpressions/RegexExtendedTests.cs
Normal file
100
test/WireMock.Net.Tests/RegularExpressions/RegexExtendedTests.cs
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
using System;
|
||||||
|
using NFluent;
|
||||||
|
using WireMock.RegularExpressions;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace WireMock.Net.Tests.RegularExpressions
|
||||||
|
{
|
||||||
|
public class RegexExtendedTests
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Input guid used for testing
|
||||||
|
/// </summary>
|
||||||
|
public Guid InputGuid { get; } = Guid.NewGuid();
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void RegexExtended_GuidB_Pattern()
|
||||||
|
{
|
||||||
|
var guidbUpper = @".*\GUIDB.*";
|
||||||
|
var guidbLower = @".*\guidb.*";
|
||||||
|
|
||||||
|
var inputLower = InputGuid.ToString("B");
|
||||||
|
var inputUpper = InputGuid.ToString("B").ToUpper();
|
||||||
|
var regexLower = new RegexExtended(guidbLower);
|
||||||
|
var regexUpper = new RegexExtended(guidbUpper);
|
||||||
|
|
||||||
|
Check.That(regexLower.IsMatch(inputLower)).Equals(true);
|
||||||
|
Check.That(regexLower.IsMatch(inputUpper)).Equals(false);
|
||||||
|
Check.That(regexUpper.IsMatch(inputUpper)).Equals(true);
|
||||||
|
Check.That(regexUpper.IsMatch(inputLower)).Equals(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void RegexExtended_GuidD_Pattern()
|
||||||
|
{
|
||||||
|
var guiddUpper = @".*\GUIDD.*";
|
||||||
|
var guiddLower = @".*\guidd.*";
|
||||||
|
|
||||||
|
var inputLower = InputGuid.ToString("D");
|
||||||
|
var inputUpper = InputGuid.ToString("D").ToUpper();
|
||||||
|
var regexLower = new RegexExtended(guiddLower);
|
||||||
|
var regexUpper = new RegexExtended(guiddUpper);
|
||||||
|
|
||||||
|
Check.That(regexLower.IsMatch(inputLower)).Equals(true);
|
||||||
|
Check.That(regexLower.IsMatch(inputUpper)).Equals(false);
|
||||||
|
Check.That(regexUpper.IsMatch(inputUpper)).Equals(true);
|
||||||
|
Check.That(regexUpper.IsMatch(inputLower)).Equals(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void RegexExtended_GuidN_Pattern()
|
||||||
|
{
|
||||||
|
var guidnUpper = @".*\GUIDN.*";
|
||||||
|
var guidnLower = @".*\guidn.*";
|
||||||
|
|
||||||
|
var inputLower = InputGuid.ToString("N");
|
||||||
|
var inputUpper = InputGuid.ToString("N").ToUpper();
|
||||||
|
var regexLower = new RegexExtended(guidnLower);
|
||||||
|
var regexUpper = new RegexExtended(guidnUpper);
|
||||||
|
|
||||||
|
Check.That(regexLower.IsMatch(inputLower)).Equals(true);
|
||||||
|
Check.That(regexLower.IsMatch(inputUpper)).Equals(false);
|
||||||
|
Check.That(regexUpper.IsMatch(inputUpper)).Equals(true);
|
||||||
|
Check.That(regexUpper.IsMatch(inputLower)).Equals(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void RegexExtended_GuidP_Pattern()
|
||||||
|
{
|
||||||
|
var guidpUpper = @".*\GUIDP.*";
|
||||||
|
var guidpLower = @".*\guidp.*";
|
||||||
|
|
||||||
|
var inputLower = InputGuid.ToString("P");
|
||||||
|
var inputUpper = InputGuid.ToString("P").ToUpper();
|
||||||
|
var regexLower = new RegexExtended(guidpLower);
|
||||||
|
var regexUpper = new RegexExtended(guidpUpper);
|
||||||
|
|
||||||
|
Check.That(regexLower.IsMatch(inputLower)).Equals(true);
|
||||||
|
Check.That(regexLower.IsMatch(inputUpper)).Equals(false);
|
||||||
|
Check.That(regexUpper.IsMatch(inputUpper)).Equals(true);
|
||||||
|
Check.That(regexUpper.IsMatch(inputLower)).Equals(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void RegexExtended_GuidX_Pattern()
|
||||||
|
{
|
||||||
|
var guidxUpper = @".*\GUIDX.*";
|
||||||
|
var guidxLower = @".*\guidx.*";
|
||||||
|
|
||||||
|
var inputLower = InputGuid.ToString("X");
|
||||||
|
var inputUpper = InputGuid.ToString("X").ToUpper().Replace("X", "x");
|
||||||
|
var regexLower = new RegexExtended(guidxLower);
|
||||||
|
var regexUpper = new RegexExtended(guidxUpper);
|
||||||
|
|
||||||
|
Check.That(regexLower.IsMatch(inputLower)).Equals(true);
|
||||||
|
Check.That(regexLower.IsMatch(inputUpper)).Equals(false);
|
||||||
|
Check.That(regexUpper.IsMatch(inputUpper)).Equals(true);
|
||||||
|
Check.That(regexUpper.IsMatch(inputLower)).Equals(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user