diff options
Diffstat (limited to 'third_party/rust/warp/tests/path.rs')
-rw-r--r-- | third_party/rust/warp/tests/path.rs | 411 |
1 files changed, 411 insertions, 0 deletions
diff --git a/third_party/rust/warp/tests/path.rs b/third_party/rust/warp/tests/path.rs new file mode 100644 index 0000000000..4f9302036e --- /dev/null +++ b/third_party/rust/warp/tests/path.rs @@ -0,0 +1,411 @@ +#![deny(warnings)] +#[macro_use] +extern crate warp; + +use futures_util::future; +use warp::Filter; + +#[tokio::test] +async fn path() { + let _ = pretty_env_logger::try_init(); + + let foo = warp::path("foo"); + let bar = warp::path(String::from("bar")); + let foo_bar = foo.and(bar.clone()); + + // /foo + let foo_req = || warp::test::request().path("/foo"); + + assert!(foo_req().matches(&foo).await); + assert!(!foo_req().matches(&bar).await); + assert!(!foo_req().matches(&foo_bar).await); + + // /foo/bar + let foo_bar_req = || warp::test::request().path("/foo/bar"); + + assert!(foo_bar_req().matches(&foo).await); + assert!(!foo_bar_req().matches(&bar).await); + assert!(foo_bar_req().matches(&foo_bar).await); +} + +#[tokio::test] +async fn param() { + let _ = pretty_env_logger::try_init(); + + let num = warp::path::param::<u32>(); + + let req = warp::test::request().path("/321"); + assert_eq!(req.filter(&num).await.unwrap(), 321); + + let s = warp::path::param::<String>(); + + let req = warp::test::request().path("/warp"); + assert_eq!(req.filter(&s).await.unwrap(), "warp"); + + // u32 doesn't extract a non-int + let req = warp::test::request().path("/warp"); + assert!(!req.matches(&num).await); + + let combo = num.map(|n| n + 5).and(s); + + let req = warp::test::request().path("/42/vroom"); + assert_eq!(req.filter(&combo).await.unwrap(), (47, "vroom".to_string())); + + // empty segments never match + let req = warp::test::request(); + assert!( + !req.matches(&s).await, + "param should never match an empty segment" + ); +} + +#[tokio::test] +async fn end() { + let _ = pretty_env_logger::try_init(); + + let foo = warp::path("foo"); + let end = warp::path::end(); + let foo_end = foo.and(end); + + assert!( + warp::test::request().path("/").matches(&end).await, + "end() matches /" + ); + + assert!( + warp::test::request() + .path("http://localhost:1234") + .matches(&end) + .await, + "end() matches /" + ); + + assert!( + warp::test::request() + .path("http://localhost:1234?q=2") + .matches(&end) + .await, + "end() matches empty path" + ); + + assert!( + warp::test::request() + .path("localhost:1234") + .matches(&end) + .await, + "end() matches authority-form" + ); + + assert!( + !warp::test::request().path("/foo").matches(&end).await, + "end() doesn't match /foo" + ); + + assert!( + warp::test::request().path("/foo").matches(&foo_end).await, + "path().and(end()) matches /foo" + ); + + assert!( + warp::test::request().path("/foo/").matches(&foo_end).await, + "path().and(end()) matches /foo/" + ); +} + +#[tokio::test] +async fn tail() { + let tail = warp::path::tail(); + + // matches full path + let ex = warp::test::request() + .path("/42/vroom") + .filter(&tail) + .await + .unwrap(); + assert_eq!(ex.as_str(), "42/vroom"); + + // matches index + let ex = warp::test::request().path("/").filter(&tail).await.unwrap(); + assert_eq!(ex.as_str(), ""); + + // doesn't include query + let ex = warp::test::request() + .path("/foo/bar?baz=quux") + .filter(&tail) + .await + .unwrap(); + assert_eq!(ex.as_str(), "foo/bar"); + + // doesn't include previously matched prefix + let and = warp::path("foo").and(tail); + let ex = warp::test::request() + .path("/foo/bar") + .filter(&and) + .await + .unwrap(); + assert_eq!(ex.as_str(), "bar"); + + // sets unmatched path index to end + let m = tail.and(warp::path("foo")); + assert!(!warp::test::request().path("/foo/bar").matches(&m).await); + + let m = tail.and(warp::path::end()); + assert!(warp::test::request().path("/foo/bar").matches(&m).await); + + let ex = warp::test::request() + .path("localhost") + .filter(&tail) + .await + .unwrap(); + assert_eq!(ex.as_str(), "/"); +} + +#[tokio::test] +async fn or() { + let _ = pretty_env_logger::try_init(); + + // /foo/bar OR /foo/baz + let foo = warp::path("foo"); + let bar = warp::path("bar"); + let baz = warp::path("baz"); + let p = foo.and(bar.or(baz)); + + // /foo/bar + let req = warp::test::request().path("/foo/bar"); + + assert!(req.matches(&p).await); + + // /foo/baz + let req = warp::test::request().path("/foo/baz"); + + assert!(req.matches(&p).await); + + // deeper nested ORs + // /foo/bar/baz OR /foo/baz/bar OR /foo/bar/bar + let p = foo + .and(bar.and(baz).map(|| panic!("shouldn't match"))) + .or(foo.and(baz.and(bar)).map(|| panic!("shouldn't match"))) + .or(foo.and(bar.and(bar))); + + // /foo/baz + let req = warp::test::request().path("/foo/baz/baz"); + assert!(!req.matches(&p).await); + + // /foo/bar/bar + let req = warp::test::request().path("/foo/bar/bar"); + assert!(req.matches(&p).await); +} + +#[tokio::test] +async fn or_else() { + let _ = pretty_env_logger::try_init(); + + let foo = warp::path("foo"); + let bar = warp::path("bar"); + + let p = foo.and(bar.or_else(|_| future::ok::<_, std::convert::Infallible>(()))); + + // /foo/bar + let req = warp::test::request().path("/foo/nope"); + + assert!(req.matches(&p).await); +} + +#[tokio::test] +async fn path_macro() { + let _ = pretty_env_logger::try_init(); + + let req = warp::test::request().path("/foo/bar"); + let p = path!("foo" / "bar"); + assert!(req.matches(&p).await); + + let req = warp::test::request().path("/foo/bar"); + let p = path!(String / "bar"); + assert_eq!(req.filter(&p).await.unwrap(), "foo"); + + let req = warp::test::request().path("/foo/bar"); + let p = path!("foo" / String); + assert_eq!(req.filter(&p).await.unwrap(), "bar"); + + // Requires path end + + let req = warp::test::request().path("/foo/bar/baz"); + let p = path!("foo" / "bar"); + assert!(!req.matches(&p).await); + + let req = warp::test::request().path("/foo/bar/baz"); + let p = path!("foo" / "bar").and(warp::path("baz")); + assert!(!req.matches(&p).await); + + // Prefix syntax + + let req = warp::test::request().path("/foo/bar/baz"); + let p = path!("foo" / "bar" / ..); + assert!(req.matches(&p).await); + + let req = warp::test::request().path("/foo/bar/baz"); + let p = path!("foo" / "bar" / ..).and(warp::path!("baz")); + assert!(req.matches(&p).await); + + // Empty + + let req = warp::test::request().path("/"); + let p = path!(); + assert!(req.matches(&p).await); + + let req = warp::test::request().path("/foo"); + let p = path!(); + assert!(!req.matches(&p).await); +} + +#[tokio::test] +async fn full_path() { + let full_path = warp::path::full(); + + let foo = warp::path("foo"); + let bar = warp::path("bar"); + let param = warp::path::param::<u32>(); + + // matches full request path + let ex = warp::test::request() + .path("/42/vroom") + .filter(&full_path) + .await + .unwrap(); + assert_eq!(ex.as_str(), "/42/vroom"); + + // matches index + let ex = warp::test::request() + .path("/") + .filter(&full_path) + .await + .unwrap(); + assert_eq!(ex.as_str(), "/"); + + // does not include query + let ex = warp::test::request() + .path("/foo/bar?baz=quux") + .filter(&full_path) + .await + .unwrap(); + assert_eq!(ex.as_str(), "/foo/bar"); + + // includes previously matched prefix + let and = foo.and(full_path); + let ex = warp::test::request() + .path("/foo/bar") + .filter(&and) + .await + .unwrap(); + assert_eq!(ex.as_str(), "/foo/bar"); + + // includes following matches + let and = full_path.and(foo); + let ex = warp::test::request() + .path("/foo/bar") + .filter(&and) + .await + .unwrap(); + assert_eq!(ex.as_str(), "/foo/bar"); + + // includes previously matched param + let and = foo.and(param).and(full_path); + let (_, ex) = warp::test::request() + .path("/foo/123") + .filter(&and) + .await + .unwrap(); + assert_eq!(ex.as_str(), "/foo/123"); + + // does not modify matching + let m = full_path.and(foo).and(bar); + assert!(warp::test::request().path("/foo/bar").matches(&m).await); + + // doesn't panic on authority-form + let ex = warp::test::request() + .path("localhost:1234") + .filter(&full_path) + .await + .unwrap(); + assert_eq!(ex.as_str(), "/"); +} + +#[tokio::test] +async fn peek() { + let peek = warp::path::peek(); + + let foo = warp::path("foo"); + let bar = warp::path("bar"); + let param = warp::path::param::<u32>(); + + // matches full request path + let ex = warp::test::request() + .path("/42/vroom") + .filter(&peek) + .await + .unwrap(); + assert_eq!(ex.as_str(), "42/vroom"); + + // matches index + let ex = warp::test::request().path("/").filter(&peek).await.unwrap(); + assert_eq!(ex.as_str(), ""); + + // does not include query + let ex = warp::test::request() + .path("/foo/bar?baz=quux") + .filter(&peek) + .await + .unwrap(); + assert_eq!(ex.as_str(), "foo/bar"); + + // does not include previously matched prefix + let and = foo.and(peek); + let ex = warp::test::request() + .path("/foo/bar") + .filter(&and) + .await + .unwrap(); + assert_eq!(ex.as_str(), "bar"); + + // includes following matches + let and = peek.and(foo); + let ex = warp::test::request() + .path("/foo/bar") + .filter(&and) + .await + .unwrap(); + assert_eq!(ex.as_str(), "foo/bar"); + + // does not include previously matched param + let and = foo.and(param).and(peek); + let (_, ex) = warp::test::request() + .path("/foo/123") + .filter(&and) + .await + .unwrap(); + assert_eq!(ex.as_str(), ""); + + // does not modify matching + let and = peek.and(foo).and(bar); + assert!(warp::test::request().path("/foo/bar").matches(&and).await); +} + +#[tokio::test] +async fn peek_segments() { + let peek = warp::path::peek(); + + // matches full request path + let ex = warp::test::request() + .path("/42/vroom") + .filter(&peek) + .await + .unwrap(); + + assert_eq!(ex.segments().collect::<Vec<_>>(), &["42", "vroom"]); + + // matches index + let ex = warp::test::request().path("/").filter(&peek).await.unwrap(); + + let segs = ex.segments().collect::<Vec<_>>(); + assert_eq!(segs, Vec::<&str>::new()); +} |