package org.jooby.internal;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.Map;
import java.util.function.Consumer;
import org.junit.Test;
public class RoutePatternTest {
class RoutePathAssert {
RoutePattern path;
public RoutePathAssert(final String method, final String pattern) {
path = new RoutePattern(method, pattern);
}
public RoutePathAssert matches(final String path) {
return matches(path, (vars) -> {
});
}
public RoutePathAssert matches(final String path, final Consumer<Map<Object, String>> vars) {
String message = this.path + " != " + path;
RouteMatcher matcher = this.path.matcher(path);
boolean matches = matcher.matches();
if (!matches) {
System.err.println(message);
}
assertTrue(message, matches);
vars.accept(matcher.vars());
return this;
}
public RoutePathAssert butNot(final String path) {
String message = this.path + " == " + path;
RouteMatcher matcher = this.path.matcher(path);
boolean matches = matcher.matches();
if (matches) {
System.err.println(message);
}
assertFalse(message, matches);
return this;
}
}
@Test
public void fixed() {
new RoutePathAssert("GET", "com/test.jsp")
.matches("GET/com/test.jsp")
.butNot("GET/com/tsst.jsp");
}
@Test
public void multipleVerb() {
new RoutePathAssert("get|POST", "com/test.jsp")
.matches("GET/com/test.jsp")
.matches("POST/com/test.jsp")
.butNot("PUT/com/test.jsp")
.butNot("DELETE/com/test.jsp")
.butNot("GET/com/tsst.jsp");
}
@Test
public void anyVerb() {
new RoutePathAssert("*", "com/test.jsp")
.matches("GET/com/test.jsp")
.matches("POST/com/test.jsp")
.butNot("GET/com/tsst.jsp");
new RoutePathAssert("*", "user/:id")
.matches("GET/user/xid", (vars) -> {
assertEquals("xid", vars.get("id"));
})
.matches("POST/user/xid2", (vars) -> {
assertEquals("xid2", vars.get("id"));
})
.butNot("GET/com/tsst.jsp");
}
@Test
public void wildOne() {
new RoutePathAssert("GET", "com/t?st.jsp")
.matches("GET/com/test.jsp")
.matches("GET/com/tsst.jsp")
.matches("GET/com/tast.jsp")
.matches("GET/com/txst.jsp")
.butNot("GET/com/test1.jsp");
}
@Test
public void wildMany() {
new RoutePathAssert("GET", "/profile/*/edit")
.matches("GET/profile/ee-00-9-k/edit")
.butNot("GET/profile/ee-00-9-k/p/edit");
new RoutePathAssert("GET", "/profile/*/*/edit")
.matches("GET/profile/ee-00-9-k/p/edit")
.butNot("GET/profile/ee-00-9-k/edit")
.butNot("GET/profile/ee-00-9-k/p/k/edit");
}
@Test
public void subdir() {
new RoutePathAssert("GET", "com/**/test.jsp")
.matches("GET/com/test.jsp")
.matches("GET/com/a/test.jsp")
.butNot("GET/com/a/testx.jsp")
.butNot("GET/org/test.jsp");
new RoutePathAssert("GET", "com/**")
.matches("GET/com/test.jsp")
.matches("GET/com/a/test.jsp")
.matches("GET/com/a/testx.jsp")
.butNot("GET/org/test.jsp");
}
@Test
public void any() {
new RoutePathAssert("GET", "com/**")
.matches("GET/com/test.jsp")
.matches("GET/com/a/test.jsp")
.matches("GET/com/a/testx.jsp")
.butNot("GET/org/test.jsp");
}
@Test
public void any2() {
new RoutePathAssert("GET", "org/**/servlet/*.html")
.matches("GET/org/jooby/servlet/test.html")
.matches("GET/org/jooby/a/servlet/test.html")
.matches("GET/org/jooby/a/b/c/servlet/test.html")
.butNot("GET/org/jooby/a/b/c/servlet/test.js");
}
@Test
public void anyNamed() {
new RoutePathAssert("GET", "com/**:rest")
.matches("GET/com/test.jsp", vars -> assertEquals("test.jsp", vars.get("rest")))
.matches("GET/com/a/test.jsp", vars -> assertEquals("a/test.jsp", vars.get("rest")))
.matches("GET/com/", vars -> assertEquals("", vars.get("rest")))
.butNot("GET/com")
.butNot("GET/test.jsp");
}
@Test
public void anyNamedSpring() {
new RoutePathAssert("GET", "com/{rest:**}")
.matches("GET/com/test.jsp", vars -> assertEquals("test.jsp", vars.get("rest")))
.matches("GET/com/a/test.jsp", vars -> assertEquals("a/test.jsp", vars.get("rest")))
.matches("GET/com/", vars -> assertEquals("", vars.get("rest")))
.butNot("GET/com")
.butNot("GET/test.jsp");
}
@Test
public void anyNamedInner() {
new RoutePathAssert("GET", "com/**:rest/bar")
.matches("GET/com/foo/bar", (vars) -> assertEquals("foo", vars.get("rest")))
.matches("GET/com/a/foo/bar", (vars) -> assertEquals("a/foo", vars.get("rest")))
.butNot("GET/com/foo/baz")
.butNot("GET/test.jsp");
}
@Test
public void anyNamedInnerSpring() {
new RoutePathAssert("GET", "com/{rest:**}/bar")
.matches("GET/com/foo/bar", (vars) -> assertEquals("foo", vars.get("rest")))
.matches("GET/com/a/foo/bar", (vars) -> assertEquals("a/foo", vars.get("rest")))
.butNot("GET/com/foo/baz")
.butNot("GET/test.jsp");
}
@Test
public void anyNamedMulti() {
new RoutePathAssert("GET", "com/**:first/bar/**:second")
.matches("GET/com/foo/bar/moo", (vars) -> {
assertEquals("foo", vars.get("first"));
assertEquals("moo", vars.get("second"));
})
.matches("GET/com/a/foo/bar/moo/baz", (vars) -> {
assertEquals("a/foo", vars.get("first"));
assertEquals("moo/baz", vars.get("second"));
})
.butNot("GET/com/foo/baz")
.butNot("GET/test.jsp");
}
@Test
public void anyNamedMultiSpring() {
new RoutePathAssert("GET", "com/{first:**}/bar/{second:**}")
.matches("GET/com/foo/bar/moo", (vars) -> {
assertEquals("foo", vars.get("first"));
assertEquals("moo", vars.get("second"));
})
.matches("GET/com/a/foo/bar/moo/baz", (vars) -> {
assertEquals("a/foo", vars.get("first"));
assertEquals("moo/baz", vars.get("second"));
})
.butNot("GET/com/foo/baz")
.butNot("GET/test.jsp");
}
@Test
public void anyNamedMultiMixed() {
new RoutePathAssert("GET", "com/**:first/bar/{second:**}")
.matches("GET/com/foo/bar/moo", (vars) -> {
assertEquals("foo", vars.get("first"));
assertEquals("moo", vars.get("second"));
})
.matches("GET/com/a/foo/bar/moo/baz", (vars) -> {
assertEquals("a/foo", vars.get("first"));
assertEquals("moo/baz", vars.get("second"));
})
.butNot("GET/com/foo/baz")
.butNot("GET/test.jsp");
}
@Test
public void anyNamedMultiMixed2() {
new RoutePathAssert("GET", "com/{first:**}/bar/**:second")
.matches("GET/com/foo/bar/moo", (vars) -> {
assertEquals("foo", vars.get("first"));
assertEquals("moo", vars.get("second"));
})
.matches("GET/com/a/foo/bar/moo/baz", (vars) -> {
assertEquals("a/foo", vars.get("first"));
assertEquals("moo/baz", vars.get("second"));
})
.butNot("GET/com/foo/baz")
.butNot("GET/test.jsp");
}
@Test
public void rootVar() {
new RoutePathAssert("GET", "{id}/list")
.matches("GET/xqi/list")
.matches("GET/123/list")
.butNot("GET/123/lisx");
}
@Test
public void mixedVar() {
new RoutePathAssert("GET", "user/:id/:name")
.matches("GET/user/xqi/n", (vars) -> {
assertEquals("xqi", vars.get("id"));
assertEquals("n", vars.get("name"));
})
.butNot("GET/user/123/x/y");
new RoutePathAssert("GET", "user/{id}/{name}")
.matches("GET/user/xqi/n", (vars) -> {
assertEquals("xqi", vars.get("id"));
assertEquals("n", vars.get("name"));
})
.butNot("GET/user/123/x/y");
new RoutePathAssert("GET", "user/{id}/:name")
.matches("GET/user/xqi/n", (vars) -> {
assertEquals("xqi", vars.get("id"));
assertEquals("n", vars.get("name"));
})
.butNot("GET/user/123/x/y");
new RoutePathAssert("GET", "user/:id/{name}")
.matches("GET/user/xqi/n", (vars) -> {
assertEquals("xqi", vars.get("id"));
assertEquals("n", vars.get("name"));
})
.butNot("GET/user/123/x/y");
}
@Test
public void var() {
new RoutePathAssert("GET", "user/{id}")
.matches("GET/user/xqi", (vars) -> {
assertEquals("xqi", vars.get("id"));
})
.matches("GET/user/123", (vars) -> {
assertEquals("123", vars.get("id"));
})
.butNot("GET/user/123/x");
new RoutePathAssert("GET", "user/:id")
.matches("GET/user/xqi", (vars) -> {
assertEquals("xqi", vars.get("id"));
})
.matches("GET/user/123", (vars) -> {
assertEquals("123", vars.get("id"));
})
.butNot("GET/user/123/x");
new RoutePathAssert("GET", "/:id")
.matches("GET/xqi", (vars) -> {
assertEquals("xqi", vars.get("id"));
})
.matches("GET/123", (vars) -> {
assertEquals("123", vars.get("id"));
})
.butNot("GET/");
new RoutePathAssert("GET", "/{id}")
.matches("GET/xqi", (vars) -> {
assertEquals("xqi", vars.get("id"));
})
.matches("GET/123", (vars) -> {
assertEquals("123", vars.get("id"));
})
.butNot("GET/");
}
@Test
public void varWithPrefix() {
new RoutePathAssert("GET", "user/p{id}")
.matches("GET/user/pxqi", (vars) -> {
assertEquals("xqi", vars.get("id"));
})
.matches("GET/user/p123", (vars) -> {
assertEquals("123", vars.get("id"));
})
.butNot("GET/user/p123/x");
new RoutePathAssert("GET", "user/p:id")
.matches("GET/user/pxqi", (vars) -> {
assertEquals("xqi", vars.get("id"));
})
.matches("GET/user/p123", (vars) -> {
assertEquals("123", vars.get("id"));
})
.butNot("GET/user/p123/x");
}
@Test
public void regex() {
new RoutePathAssert("GET", "user/{id:\\d+}")
.matches("GET/user/123", (vars) -> {
assertEquals("123", vars.get("id"));
})
.butNot("GET/user/123/x")
.butNot("GET/user/123x")
.butNot("GET/user/xqi");
}
@Test
public void antExamples() {
new RoutePathAssert("GET", "*.java")
.matches("GET/.java")
.matches("GET/x.java")
.matches("GET/FooBar.java")
.butNot("GET/FooBar.xml");
new RoutePathAssert("GET", "?.java")
.matches("GET/x.java")
.matches("GET/A.java")
.butNot("GET/.java")
.butNot("GET/xyz.java");
new RoutePathAssert("GET", "**/CVS/*")
.matches("GET/CVS/Repository")
.matches("GET/org/apache/CVS/Entries")
.matches("GET/org/apache/jakarta/tools/ant/CVS/Entries")
.butNot("GET/org/apache/CVS/foo/bar/Entries");
new RoutePathAssert("GET", "org/apache/jakarta/**")
.matches("GET/org/apache/jakarta/tools/ant/docs/index.html")
.matches("GET/org/apache/jakarta/test.xml")
.butNot("GET/org/apache/xyz.java");
new RoutePathAssert("GET", "org/apache/**/CVS/*")
.matches("GET/org/apache/CVS/Entries")
.matches("GET/org/apache/jakarta/tools/ant/CVS/Entries")
.butNot("GET/org/apache/CVS/foo/bar/Entries");
}
@Test
public void moreExpression() {
new RoutePathAssert("GET", "/views/products/**/*.cfm")
.matches("GET/views/products/index.cfm")
.matches("GET/views/products/SE10/index.cfm")
.matches("GET/views/products/SE10/details.cfm")
.matches("GET/views/products/ST80/index.cfm")
.matches("GET/views/products/ST80/details.cfm")
.butNot("GET/views/index.cfm")
.butNot("GET/views/aboutUs/index.cfm")
.butNot("GET/views/aboutUs/managementTeam.cfm");
new RoutePathAssert("GET", "/views/index??.cfm")
.matches("GET/views/index01.cfm")
.matches("GET/views/index02.cfm")
.matches("GET/views/indexAA.cfm")
.butNot("GET/views/index01.htm")
.butNot("GET/views/index1.cfm")
.butNot("GET/views/indexOther.cfm")
.butNot("GET/views/anotherDir/index01.cfm");
}
@Test
public void normalizePath() {
assertEquals("/", new RoutePattern("GET", "/").pattern());
assertEquals("/", new RoutePattern("GET", "//").pattern());
assertEquals("/foo", new RoutePattern("GET", "/foo//").pattern());
assertEquals("/foo", new RoutePattern("GET", "foo//").pattern());
assertEquals("/foo", new RoutePattern("GET", "foo").pattern());
assertEquals("/foo", new RoutePattern("GET", "foo/").pattern());
assertEquals("/foo/bar", new RoutePattern("GET", "/foo//bar").pattern());
}
@Test
public void capturingGroups() {
new RoutePathAssert("GET", "/js/*/2.1.3/*")
.matches("GET/js/jquery/2.1.3/jquery.js", vars -> {
assertEquals("jquery", vars.get(0));
assertEquals("jquery.js", vars.get(1));
});
new RoutePathAssert("GET", "/js/**")
.matches("GET/js/jquery/2.1.3/jquery.js", vars -> {
assertEquals("jquery/2.1.3/jquery.js", vars.get(0));
});
new RoutePathAssert("GET", "/js/**/*.js")
.matches("GET/js/jquery/2.1.3/jquery.js", vars -> {
assertEquals("jquery/2.1.3/jquery", vars.get(0));
});
}
@Test
public void cornerCase() {
new RoutePathAssert("GET", "/search/**")
.matches("GET/search");
new RoutePathAssert("GET", "/m/**")
.butNot("GET/merge/login");
}
}