From 73bd1c507262f9a7632223dbc397ede1b12da1cf Mon Sep 17 00:00:00 2001 From: Lilith River Date: Tue, 11 Jun 2024 22:28:53 -0600 Subject: [PATCH] Adds starts-i, ends-i, and starts-chars aliases for consistency. --- .../Matching/StringCondition.cs | 3 + .../Routing/Matching/MatchExpressionTests.cs | 111 ++++++++++-------- 2 files changed, 67 insertions(+), 47 deletions(-) diff --git a/src/Imazen.Routing/Matching/StringCondition.cs b/src/Imazen.Routing/Matching/StringCondition.cs index cbb574b..2033044 100644 --- a/src/Imazen.Routing/Matching/StringCondition.cs +++ b/src/Imazen.Routing/Matching/StringCondition.cs @@ -600,7 +600,10 @@ internal static string NormalizeAliases(string name) "eq" => "equals", "" => "equals", "starts" => "starts-with", + "starts-chars" => "starts-with-chars", + "starts-i" => "starts-with-i", "ends" => "ends-with", + "ends-i" => "ends-with-i", "includes" => "contains", "includes-i" => "contains-i", "image-extension-supported" => "image-ext-supported", diff --git a/tests/ImazenShared.Tests/Routing/Matching/MatchExpressionTests.cs b/tests/ImazenShared.Tests/Routing/Matching/MatchExpressionTests.cs index d86321b..d3edb2c 100644 --- a/tests/ImazenShared.Tests/Routing/Matching/MatchExpressionTests.cs +++ b/tests/ImazenShared.Tests/Routing/Matching/MatchExpressionTests.cs @@ -62,7 +62,7 @@ public void TestAll(bool s, string expr, params string[] inputs) } } [Theory] - [InlineData("/{name:ends-with(y)}", "/cody", "name=cody")] + [InlineData("/{name:ends(y)}", "/cody", "name=cody")] // ints [InlineData("{:int}", "123", "int=123")] [InlineData("{:int}", "-123", "int=-123")] @@ -109,9 +109,9 @@ public void TestCaptures(string expr, string input, string? expectedCaptures) } [Theory] - [InlineData("{name:starts-with(foo):ends-with(bar)?}", false)] - [InlineData("{name:starts-with(foo):ends-with(bar)}", true)] - [InlineData("{name:starts-with(foo):?}", true)] + [InlineData("{name:starts(foo):ends(bar)?}", false)] + [InlineData("{name:starts(foo):ends(bar)}", true)] + [InlineData("{name:starts(foo):?}", true)] [InlineData("{name:prefix(foo):suffix(bar)}", true)] [InlineData("prefix(foo){name}suffix(bar)", true)] [InlineData("{name:len(5):alpha()}", true)] @@ -119,23 +119,23 @@ public void TestCaptures(string expr, string input, string? expectedCaptures) [InlineData("{name:len(5)}", true)] [InlineData("{name:equals(foo):equals(bar)}", false)] [InlineData("{name:equals(foo|bar)}", true)] - [InlineData("{name:starts-with(foo)}suffix(bar)", true)] //suffix(bar) will be seen as a literal - [InlineData("{name:starts-with(foo)}/suffix(bar)", true)] - [InlineData("{name:starts-with(foo)}:ends-with(baz)suffix(bar)", true)] + [InlineData("{name:starts(foo)}suffix(bar)", true)] //suffix(bar) will be seen as a literal + [InlineData("{name:starts(foo)}/suffix(bar)", true)] + [InlineData("{name:starts(foo)}:ends(baz)suffix(bar)", true)] [InlineData("{?}", true)] [InlineData("{*}", true)] [InlineData("{:?}", true)] [InlineData("{name:?}", true)] [InlineData("{name:int32}", true)] [InlineData("{name:int32()}", true)] - [InlineData("{name:starts-with(foo}:ends-with(bar)}", false)] - [InlineData("{name:starts-with(foo):ends-with(bar)}{:alpha()}", true)] - [InlineData("{name:starts-with(foo):ends-with(bar)}/{:alpha()}", true)] - [InlineData("{name:starts-with(foo)}{:ends-with(bar):alpha()}", false)] + [InlineData("{name:starts(foo}:ends(bar)}", false)] + [InlineData("{name:starts(foo):ends(bar)}{:alpha()}", true)] + [InlineData("{name:starts(foo):ends(bar)}/{:alpha()}", true)] + [InlineData("{name:starts(foo)}{:ends(bar):alpha()}", false)] [InlineData("{name:prefix(foo):?}", true)] [InlineData("{name:suffix(bar)}", true)] [InlineData("{name:suffix(bar):?}", true)] - [InlineData("{name:ends-with(bar):?}", true)] + [InlineData("{name:ends(bar):?}", true)] [InlineData("{name:contains(foo)}", true)] [InlineData("{name:contains(foo):?}", true)] [InlineData("{name:contains-i(foo)}", true)] @@ -143,10 +143,10 @@ public void TestCaptures(string expr, string input, string? expectedCaptures) [InlineData("{name:equals(foo):?}", true)] [InlineData("{name:equals-i(foo)}", true)] [InlineData("{name:equals-i(foo):?}", true)] - [InlineData("{name:starts-with-i(foo)}", true)] - [InlineData("{name:starts-with-i(foo):?}", true)] - [InlineData("{name:ends-with-i(bar)}", true)] - [InlineData("{name:ends-with-i(bar):?}", true)] + [InlineData("{name:starts-i(foo)}", true)] + [InlineData("{name:starts-i(foo):?}", true)] + [InlineData("{name:ends-i(bar)}", true)] + [InlineData("{name:ends-i(bar):?}", true)] [InlineData("{name:len(5,10)}", true)] [InlineData("{name:len(5,10):?}", true)] [InlineData("{name:length(,5)}", true)] @@ -173,14 +173,14 @@ public void TestCaptures(string expr, string input, string? expectedCaptures) [InlineData("{name:equals(foo|bar|baz):?}", true)] [InlineData("{name:equals-i(foo|bar|baz)}", true)] [InlineData("{name:equals-i(foo|bar|baz):?}", true)] - [InlineData("{name:starts-with(foo|bar|baz)}", true)] - [InlineData("{name:starts-with(foo|bar|baz):?}", true)] - [InlineData("{name:starts-with-i(foo|bar|baz)}", true)] - [InlineData("{name:starts-with-i(foo|bar|baz):?}", true)] - [InlineData("{name:ends-with(foo|bar|baz)}", true)] - [InlineData("{name:ends-with(foo|bar|baz):?}", true)] - [InlineData("{name:ends-with-i(foo|bar|baz)}", true)] - [InlineData("{name:ends-with-i(foo|bar|baz):?}", true)] + [InlineData("{name:starts(foo|bar|baz)}", true)] + [InlineData("{name:starts(foo|bar|baz):?}", true)] + [InlineData("{name:starts-i(foo|bar|baz)}", true)] + [InlineData("{name:starts-i(foo|bar|baz):?}", true)] + [InlineData("{name:ends(foo|bar|baz)}", true)] + [InlineData("{name:ends(foo|bar|baz):?}", true)] + [InlineData("{name:ends-i(foo|bar|baz)}", true)] + [InlineData("{name:ends-i(foo|bar|baz):?}", true)] [InlineData("{name:contains(foo|bar|baz)}", true)] [InlineData("{name:contains(foo|bar|baz):?}", true)] [InlineData("{name:contains-i(foo|bar|baz)}", true)] @@ -191,29 +191,29 @@ public void TestCaptures(string expr, string input, string? expectedCaptures) [InlineData("{name:image-ext-supported:?}", true)] [InlineData("{name:allowed-chars([a-zA-Z0-9_\\-])}", true)] [InlineData("{name:allowed-chars([a-zA-Z0-9_\\-]):?}", true)] - [InlineData("{name:starts-with-chars(3,[a-zA-Z])}", true)] - [InlineData("{name:starts-with-chars(3,[a-zA-Z]):?}", true)] - [InlineData("{name:ends-with([$%^])}", true)] - [InlineData("{name:ends-with([$%^]):?}", true)] - [InlineData("{name:ends-with-i([$%^])}", true)] - [InlineData("{name:ends-with-i([$%^]):?}", true)] - [InlineData("{name:starts-with([0-9])}", true)] - [InlineData("{name:starts-with([0-9]):?}", true)] - [InlineData("{name:starts-with-i([0-9])}", true)] - [InlineData("{name:starts-with-i([0-9]):?}", true)] - [InlineData("{name:starts-with([aeiouAEIOU])}", true)] - [InlineData("{name:starts-with([aeiouAEIOU]):?}", true)] - [InlineData("{name:starts-with-i([aeiouAEIOU])}", true)] - [InlineData("{name:starts-with-i([aeiouAEIOU]):?}", true)] - [InlineData("{name:ends-with([!@#$%^&*])}", true)] - [InlineData("{name:ends-with([!@#$%^&*]):?}", true)] - [InlineData("{name:ends-with-i([!@#$%^&*])}", true)] - [InlineData("{name:ends-with-i([!@#$%^&*]):?}", true)] - [InlineData("{name:ends-with([aeiouAEIOU])}", true)] - [InlineData("{name:ends-with([aeiouAEIOU]):?}", true)] - [InlineData("{name:ends-with-i([aeiouAEIOU])}", true)] - [InlineData("{name:ends-with-i([aeiouAEIOU]):?}", true)] - [InlineData("{name:ends-with-i([aeiouAEIOU]|[a-z]):?}", false)] + [InlineData("{name:starts-chars(3,[a-zA-Z])}", true)] + [InlineData("{name:starts-chars(3,[a-zA-Z]):?}", true)] + [InlineData("{name:ends([$%^])}", true)] + [InlineData("{name:ends([$%^]):?}", true)] + [InlineData("{name:ends-i([$%^])}", true)] + [InlineData("{name:ends-i([$%^]):?}", true)] + [InlineData("{name:starts([0-9])}", true)] + [InlineData("{name:starts([0-9]):?}", true)] + [InlineData("{name:starts-i([0-9])}", true)] + [InlineData("{name:starts-i([0-9]):?}", true)] + [InlineData("{name:starts([aeiouAEIOU])}", true)] + [InlineData("{name:starts([aeiouAEIOU]):?}", true)] + [InlineData("{name:starts-i([aeiouAEIOU])}", true)] + [InlineData("{name:starts-i([aeiouAEIOU]):?}", true)] + [InlineData("{name:ends([!@#$%^&*])}", true)] + [InlineData("{name:ends([!@#$%^&*]):?}", true)] + [InlineData("{name:ends-i([!@#$%^&*])}", true)] + [InlineData("{name:ends-i([!@#$%^&*]):?}", true)] + [InlineData("{name:ends([aeiouAEIOU])}", true)] + [InlineData("{name:ends([aeiouAEIOU]):?}", true)] + [InlineData("{name:ends-i([aeiouAEIOU])}", true)] + [InlineData("{name:ends-i([aeiouAEIOU]):?}", true)] + [InlineData("{name:ends-i([aeiouAEIOU]|[a-z]):?}", false)] // Ensure that they won't parse if we use any aliases or conditions as names [InlineData("{int}", false)] [InlineData("{uint}", false)] @@ -221,6 +221,23 @@ public void TestCaptures(string expr, string input, string? expectedCaptures) [InlineData("{alphanumeric}", false)] [InlineData("{hex}", false)] [InlineData("{guid}", false)] + [InlineData("{:guid}", true)] + [InlineData("{:int}", true)] + [InlineData("{:u32}", true)] + [InlineData("{:u64}", true)] + [InlineData("{:int32}", true)] + [InlineData("{:int64}", true)] + [InlineData("{:alpha}", true)] + [InlineData("{:alpha-lower}", true)] + [InlineData("{:alpha-upper}", true)] + [InlineData("{:alphanumeric}", true)] + [InlineData("{:i32}", true)] + [InlineData("{:i64}", true)] + [InlineData("{:(literal)}", true)] + [InlineData("{:starts-with-i(hi)}", true)] + [InlineData("{:starts-with(hi)}", true)] + [InlineData("{:ends-with-i(hi)}", true)] + [InlineData("{:ends-with(hi)}", true)] public void TestMatchExpressionParsing(string expression, bool shouldParse) { var context = MatchingContext.DefaultCaseInsensitive;