Vendor dependencies

This commit is contained in:
2026-08-01 16:11:49 +03:00
parent 7f139a0241
commit 6b5e7f0f8b
29706 changed files with 9575646 additions and 0 deletions
+243
View File
@@ -0,0 +1,243 @@
use matchit::{InsertError, Router};
struct InsertTest(Vec<(&'static str, Result<(), InsertError>)>);
impl InsertTest {
fn run(self) {
let mut router = Router::new();
for (route, expected) in self.0 {
let got = router.insert(route, route.to_owned());
assert_eq!(got, expected, "{route}");
}
}
}
fn conflict(with: &'static str) -> InsertError {
InsertError::Conflict { with: with.into() }
}
#[test]
fn wildcard_conflict() {
InsertTest(vec![
("/cmd/{tool}/{sub}", Ok(())),
("/cmd/vet", Ok(())),
("/foo/bar", Ok(())),
("/foo/{name}", Ok(())),
("/foo/{names}", Err(conflict("/foo/{name}"))),
("/cmd/{*path}", Err(conflict("/cmd/{tool}/{sub}"))),
("/cmd/{xxx}/names", Ok(())),
("/cmd/{tool}/{xxx}/foo", Ok(())),
("/src/{*filepath}", Ok(())),
("/src/{file}", Err(conflict("/src/{*filepath}"))),
("/src/static.json", Ok(())),
("/src/$filepathx", Ok(())),
("/src/", Ok(())),
("/src/foo/bar", Ok(())),
("/src1/", Ok(())),
("/src1/{*filepath}", Ok(())),
("/src2{*filepath}", Ok(())),
("/src2/{*filepath}", Ok(())),
("/src2/", Ok(())),
("/src2", Ok(())),
("/src3", Ok(())),
("/src3/{*filepath}", Ok(())),
("/search/{query}", Ok(())),
("/search/valid", Ok(())),
("/user_{name}", Ok(())),
("/user_x", Ok(())),
("/user_{bar}", Err(conflict("/user_{name}"))),
("/id{id}", Ok(())),
("/id/{id}", Ok(())),
])
.run()
}
#[test]
fn invalid_catchall() {
InsertTest(vec![
("/non-leading-{*catchall}", Ok(())),
("/foo/bar{*catchall}", Ok(())),
("/src/{*filepath}/x", Err(InsertError::InvalidCatchAll)),
("/src2/", Ok(())),
("/src2/{*filepath}/x", Err(InsertError::InvalidCatchAll)),
])
.run()
}
#[test]
fn catchall_root_conflict() {
InsertTest(vec![("/", Ok(())), ("/{*filepath}", Ok(()))]).run()
}
#[test]
fn child_conflict() {
InsertTest(vec![
("/cmd/vet", Ok(())),
("/cmd/{tool}", Ok(())),
("/cmd/{tool}/{sub}", Ok(())),
("/cmd/{tool}/misc", Ok(())),
("/cmd/{tool}/{bad}", Err(conflict("/cmd/{tool}/{sub}"))),
("/src/AUTHORS", Ok(())),
("/src/{*filepath}", Ok(())),
("/user_x", Ok(())),
("/user_{name}", Ok(())),
("/id/{id}", Ok(())),
("/id{id}", Ok(())),
("/{id}", Ok(())),
("/{*filepath}", Err(conflict("/{id}"))),
])
.run()
}
#[test]
fn duplicates() {
InsertTest(vec![
("/", Ok(())),
("/", Err(conflict("/"))),
("/doc/", Ok(())),
("/doc/", Err(conflict("/doc/"))),
("/src/{*filepath}", Ok(())),
("/src/{*filepath}", Err(conflict("/src/{*filepath}"))),
("/search/{query}", Ok(())),
("/search/{query}", Err(conflict("/search/{query}"))),
("/user_{name}", Ok(())),
("/user_{name}", Err(conflict("/user_{name}"))),
])
.run()
}
#[test]
fn unnamed_param() {
InsertTest(vec![
("/{}", Err(InsertError::InvalidParam)),
("/user{}/", Err(InsertError::InvalidParam)),
("/cmd/{}/", Err(InsertError::InvalidParam)),
("/src/{*}", Err(InsertError::InvalidParam)),
])
.run()
}
#[test]
fn double_params() {
InsertTest(vec![
("/{foo}{bar}", Err(InsertError::InvalidParamSegment)),
("/{foo}{bar}/", Err(InsertError::InvalidParamSegment)),
("/{foo}{{*bar}/", Err(InsertError::InvalidParamSegment)),
])
.run()
}
#[test]
fn normalized_conflict() {
InsertTest(vec![
("/x/{foo}/bar", Ok(())),
("/x/{bar}/bar", Err(conflict("/x/{foo}/bar"))),
("/{y}/bar/baz", Ok(())),
("/{y}/baz/baz", Ok(())),
("/{z}/bar/bat", Ok(())),
("/{z}/bar/baz", Err(conflict("/{y}/bar/baz"))),
])
.run()
}
#[test]
fn more_conflicts() {
InsertTest(vec![
("/con{tact}", Ok(())),
("/who/are/{*you}", Ok(())),
("/who/foo/hello", Ok(())),
("/whose/{users}/{name}", Ok(())),
("/who/are/foo", Ok(())),
("/who/are/foo/bar", Ok(())),
("/con{nection}", Err(conflict("/con{tact}"))),
(
"/whose/{users}/{user}",
Err(conflict("/whose/{users}/{name}")),
),
])
.run()
}
#[test]
fn catchall_static_overlap() {
InsertTest(vec![
("/bar", Ok(())),
("/bar/", Ok(())),
("/bar/{*foo}", Ok(())),
])
.run();
InsertTest(vec![
("/foo", Ok(())),
("/{*bar}", Ok(())),
("/bar", Ok(())),
("/baz", Ok(())),
("/baz/{split}", Ok(())),
("/", Ok(())),
("/{*bar}", Err(conflict("/{*bar}"))),
("/{*zzz}", Err(conflict("/{*bar}"))),
("/{xxx}", Err(conflict("/{*bar}"))),
])
.run();
InsertTest(vec![
("/{*bar}", Ok(())),
("/bar", Ok(())),
("/bar/x", Ok(())),
("/bar_{x}", Ok(())),
("/bar_{x}", Err(conflict("/bar_{x}"))),
("/bar_{x}/y", Ok(())),
("/bar/{x}", Ok(())),
])
.run();
}
#[test]
fn duplicate_conflict() {
InsertTest(vec![
("/hey", Ok(())),
("/hey/users", Ok(())),
("/hey/user", Ok(())),
("/hey/user", Err(conflict("/hey/user"))),
])
.run()
}
#[test]
fn invalid_param() {
InsertTest(vec![
("{", Err(InsertError::InvalidParam)),
("}", Err(InsertError::InvalidParam)),
("x{y", Err(InsertError::InvalidParam)),
("x}", Err(InsertError::InvalidParam)),
("/{foo}s", Err(InsertError::InvalidParamSegment)),
])
.run();
}
#[test]
fn escaped_param() {
InsertTest(vec![
("{{", Ok(())),
("}}", Ok(())),
("xx}}", Ok(())),
("}}yy", Ok(())),
("}}yy{{}}", Ok(())),
("}}yy{{}}{{}}y{{", Ok(())),
("}}yy{{}}{{}}y{{", Err(conflict("}yy{}{}y{"))),
("/{{yy", Ok(())),
("/{yy}", Ok(())),
("/foo", Ok(())),
("/foo/{{", Ok(())),
("/foo/{{/{x}", Ok(())),
("/foo/{ba{{r}", Ok(())),
("/bar/{ba}}r}", Ok(())),
("/xxx/{x{{}}y}", Ok(())),
])
.run()
}
#[test]
fn bare_catchall() {
InsertTest(vec![("{*foo}", Ok(())), ("foo/{*bar}", Ok(()))]).run()
}
File diff suppressed because it is too large Load Diff
+265
View File
@@ -0,0 +1,265 @@
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();
}