Skip to content

Commit

Permalink
Adds starts-i, ends-i, and starts-chars aliases for consistency.
Browse files Browse the repository at this point in the history
  • Loading branch information
lilith committed Jun 12, 2024
1 parent c41bc3c commit 73bd1c5
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 47 deletions.
3 changes: 3 additions & 0 deletions src/Imazen.Routing/Matching/StringCondition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
111 changes: 64 additions & 47 deletions tests/ImazenShared.Tests/Routing/Matching/MatchExpressionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down Expand Up @@ -109,44 +109,44 @@ 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)]
[InlineData("{name:alpha():length(5,10)}", true)]
[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)]
[InlineData("{name:contains-i(foo):?}", true)]
[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)]
Expand All @@ -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)]
Expand All @@ -191,36 +191,53 @@ 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)]
[InlineData("{alpha}", false)]
[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;
Expand Down

0 comments on commit 73bd1c5

Please sign in to comment.