266 lines
7.4 KiB
Rust
266 lines
7.4 KiB
Rust
use matchit::Router;
|
|
|
|
struct RemoveTest {
|
|
routes: Vec<&'static str>,
|
|
ops: Vec<(Operation, &'static str, Option<&'static str>)>,
|
|
remaining: Vec<&'static str>,
|
|
}
|
|
|
|
enum Operation {
|
|
Insert,
|
|
Remove,
|
|
}
|
|
|
|
use Operation::*;
|
|
|
|
impl RemoveTest {
|
|
fn run(self) {
|
|
let mut router = Router::new();
|
|
|
|
for route in self.routes.iter() {
|
|
assert_eq!(router.insert(*route, route.to_owned()), Ok(()), "{route}");
|
|
}
|
|
|
|
for (op, route, expected) in self.ops.iter() {
|
|
match op {
|
|
Insert => {
|
|
assert_eq!(router.insert(*route, route), Ok(()), "{route}")
|
|
}
|
|
Remove => {
|
|
assert_eq!(router.remove(*route), *expected, "removing {route}",)
|
|
}
|
|
}
|
|
}
|
|
|
|
for route in self.remaining {
|
|
assert!(matches!(router.at(route), Ok(_)), "remaining {route}");
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn normalized() {
|
|
RemoveTest {
|
|
routes: vec![
|
|
"/x/{foo}/bar",
|
|
"/x/{bar}/baz",
|
|
"/{foo}/{baz}/bax",
|
|
"/{foo}/{bar}/baz",
|
|
"/{fod}/{baz}/{bax}/foo",
|
|
"/{fod}/baz/bax/foo",
|
|
"/{foo}/baz/bax",
|
|
"/{bar}/{bay}/bay",
|
|
"/s",
|
|
"/s/s",
|
|
"/s/s/s",
|
|
"/s/s/s/s",
|
|
"/s/s/{s}/x",
|
|
"/s/s/{y}/d",
|
|
],
|
|
ops: vec![
|
|
(Remove, "/x/{foo}/bar", Some("/x/{foo}/bar")),
|
|
(Remove, "/x/{bar}/baz", Some("/x/{bar}/baz")),
|
|
(Remove, "/{foo}/{baz}/bax", Some("/{foo}/{baz}/bax")),
|
|
(Remove, "/{foo}/{bar}/baz", Some("/{foo}/{bar}/baz")),
|
|
(
|
|
Remove,
|
|
"/{fod}/{baz}/{bax}/foo",
|
|
Some("/{fod}/{baz}/{bax}/foo"),
|
|
),
|
|
(Remove, "/{fod}/baz/bax/foo", Some("/{fod}/baz/bax/foo")),
|
|
(Remove, "/{foo}/baz/bax", Some("/{foo}/baz/bax")),
|
|
(Remove, "/{bar}/{bay}/bay", Some("/{bar}/{bay}/bay")),
|
|
(Remove, "/s", Some("/s")),
|
|
(Remove, "/s/s", Some("/s/s")),
|
|
(Remove, "/s/s/s", Some("/s/s/s")),
|
|
(Remove, "/s/s/s/s", Some("/s/s/s/s")),
|
|
(Remove, "/s/s/{s}/x", Some("/s/s/{s}/x")),
|
|
(Remove, "/s/s/{y}/d", Some("/s/s/{y}/d")),
|
|
],
|
|
remaining: vec![],
|
|
}
|
|
.run();
|
|
}
|
|
|
|
#[test]
|
|
fn test() {
|
|
RemoveTest {
|
|
routes: vec!["/home", "/home/{id}"],
|
|
ops: vec![
|
|
(Remove, "/home", Some("/home")),
|
|
(Remove, "/home", None),
|
|
(Remove, "/home/{id}", Some("/home/{id}")),
|
|
(Remove, "/home/{id}", None),
|
|
],
|
|
remaining: vec![],
|
|
}
|
|
.run();
|
|
}
|
|
|
|
#[test]
|
|
fn blog() {
|
|
RemoveTest {
|
|
routes: vec![
|
|
"/{page}",
|
|
"/posts/{year}/{month}/{post}",
|
|
"/posts/{year}/{month}/index",
|
|
"/posts/{year}/top",
|
|
"/static/{*path}",
|
|
"/favicon.ico",
|
|
],
|
|
ops: vec![
|
|
(Remove, "/{page}", Some("/{page}")),
|
|
(
|
|
Remove,
|
|
"/posts/{year}/{month}/{post}",
|
|
Some("/posts/{year}/{month}/{post}"),
|
|
),
|
|
(
|
|
Remove,
|
|
"/posts/{year}/{month}/index",
|
|
Some("/posts/{year}/{month}/index"),
|
|
),
|
|
(Remove, "/posts/{year}/top", Some("/posts/{year}/top")),
|
|
(Remove, "/static/{*path}", Some("/static/{*path}")),
|
|
(Remove, "/favicon.ico", Some("/favicon.ico")),
|
|
],
|
|
remaining: vec![],
|
|
}
|
|
.run()
|
|
}
|
|
|
|
#[test]
|
|
fn catchall() {
|
|
RemoveTest {
|
|
routes: vec!["/foo/{*catchall}", "/bar", "/bar/", "/bar/{*catchall}"],
|
|
ops: vec![
|
|
(Remove, "/foo/{*catchall}", Some("/foo/{*catchall}")),
|
|
(Remove, "/bar/", Some("/bar/")),
|
|
(Insert, "/foo/*catchall", Some("/foo/*catchall")),
|
|
(Remove, "/bar/{*catchall}", Some("/bar/{*catchall}")),
|
|
],
|
|
remaining: vec!["/bar", "/foo/*catchall"],
|
|
}
|
|
.run();
|
|
}
|
|
|
|
#[test]
|
|
fn overlapping_routes() {
|
|
RemoveTest {
|
|
routes: vec![
|
|
"/home",
|
|
"/home/{id}",
|
|
"/users",
|
|
"/users/{id}",
|
|
"/users/{id}/posts",
|
|
"/users/{id}/posts/{post_id}",
|
|
"/articles",
|
|
"/articles/{category}",
|
|
"/articles/{category}/{id}",
|
|
],
|
|
ops: vec![
|
|
(Remove, "/home", Some("/home")),
|
|
(Insert, "/home", Some("/home")),
|
|
(Remove, "/home/{id}", Some("/home/{id}")),
|
|
(Insert, "/home/{id}", Some("/home/{id}")),
|
|
(Remove, "/users", Some("/users")),
|
|
(Insert, "/users", Some("/users")),
|
|
(Remove, "/users/{id}", Some("/users/{id}")),
|
|
(Insert, "/users/{id}", Some("/users/{id}")),
|
|
(Remove, "/users/{id}/posts", Some("/users/{id}/posts")),
|
|
(Insert, "/users/{id}/posts", Some("/users/{id}/posts")),
|
|
(
|
|
Remove,
|
|
"/users/{id}/posts/{post_id}",
|
|
Some("/users/{id}/posts/{post_id}"),
|
|
),
|
|
(
|
|
Insert,
|
|
"/users/{id}/posts/{post_id}",
|
|
Some("/users/{id}/posts/{post_id}"),
|
|
),
|
|
(Remove, "/articles", Some("/articles")),
|
|
(Insert, "/articles", Some("/articles")),
|
|
(Remove, "/articles/{category}", Some("/articles/{category}")),
|
|
(Insert, "/articles/{category}", Some("/articles/{category}")),
|
|
(
|
|
Remove,
|
|
"/articles/{category}/{id}",
|
|
Some("/articles/{category}/{id}"),
|
|
),
|
|
(
|
|
Insert,
|
|
"/articles/{category}/{id}",
|
|
Some("/articles/{category}/{id}"),
|
|
),
|
|
],
|
|
remaining: vec![
|
|
"/home",
|
|
"/home/{id}",
|
|
"/users",
|
|
"/users/{id}",
|
|
"/users/{id}/posts",
|
|
"/users/{id}/posts/{post_id}",
|
|
"/articles",
|
|
"/articles/{category}",
|
|
"/articles/{category}/{id}",
|
|
],
|
|
}
|
|
.run();
|
|
}
|
|
|
|
#[test]
|
|
fn trailing_slash() {
|
|
RemoveTest {
|
|
routes: vec!["/{home}/", "/foo"],
|
|
ops: vec![
|
|
(Remove, "/", None),
|
|
(Remove, "/{home}", None),
|
|
(Remove, "/foo/", None),
|
|
(Remove, "/foo", Some("/foo")),
|
|
(Remove, "/{home}", None),
|
|
(Remove, "/{home}/", Some("/{home}/")),
|
|
],
|
|
remaining: vec![],
|
|
}
|
|
.run();
|
|
}
|
|
|
|
#[test]
|
|
fn remove_root() {
|
|
RemoveTest {
|
|
routes: vec!["/"],
|
|
ops: vec![(Remove, "/", Some("/"))],
|
|
remaining: vec![],
|
|
}
|
|
.run();
|
|
}
|
|
|
|
#[test]
|
|
fn check_escaped_params() {
|
|
RemoveTest {
|
|
routes: vec![
|
|
"/foo/{id}",
|
|
"/foo/{id}/bar",
|
|
"/bar/{user}/{id}",
|
|
"/bar/{user}/{id}/baz",
|
|
"/baz/{product}/{user}/{id}",
|
|
],
|
|
ops: vec![
|
|
(Remove, "/foo/{a}", None),
|
|
(Remove, "/foo/{a}/bar", None),
|
|
(Remove, "/bar/{a}/{b}", None),
|
|
(Remove, "/bar/{a}/{b}/baz", None),
|
|
(Remove, "/baz/{a}/{b}/{c}", None),
|
|
],
|
|
remaining: vec![
|
|
"/foo/{id}",
|
|
"/foo/{id}/bar",
|
|
"/bar/{user}/{id}",
|
|
"/bar/{user}/{id}/baz",
|
|
"/baz/{product}/{user}/{id}",
|
|
],
|
|
}
|
|
.run();
|
|
}
|