From e05f9bb9639658c159c8097316d8b8d6a631c986 Mon Sep 17 00:00:00 2001 From: Dominic Date: Fri, 8 May 2020 18:39:11 +0200 Subject: [PATCH] a whole bunch of tests for the method macros --- derive/src/lib.rs | 4 +- derive/src/method.rs | 15 ++- example/src/main.rs | 8 +- tests/async_methods.rs | 106 ++++++++++++++++++++ tests/custom_request_body.rs | 10 +- tests/openapi_supports_scope.rs | 20 ++-- tests/sync_methods.rs | 106 ++++++++++++++++++++ tests/trybuild_ui.rs | 7 ++ tests/ui/method_async_state.rs | 15 +++ tests/ui/method_async_state.stderr | 21 ++++ tests/ui/method_for_unknown_resource.rs | 10 ++ tests/ui/method_for_unknown_resource.stderr | 5 + tests/ui/method_no_resource.rs | 14 +++ tests/ui/method_no_resource.stderr | 15 +++ tests/ui/method_self.rs | 14 +++ tests/ui/method_self.stderr | 13 +++ tests/ui/method_too_few_args.rs | 14 +++ tests/ui/method_too_few_args.stderr | 13 +++ tests/ui/method_too_many_args.rs | 14 +++ tests/ui/method_too_many_args.stderr | 13 +++ tests/ui/method_unsafe.rs | 14 +++ tests/ui/method_unsafe.stderr | 13 +++ tests/util/mod.rs | 37 +++++++ 23 files changed, 473 insertions(+), 28 deletions(-) create mode 100644 tests/async_methods.rs create mode 100644 tests/sync_methods.rs create mode 100644 tests/ui/method_async_state.rs create mode 100644 tests/ui/method_async_state.stderr create mode 100644 tests/ui/method_for_unknown_resource.rs create mode 100644 tests/ui/method_for_unknown_resource.stderr create mode 100644 tests/ui/method_no_resource.rs create mode 100644 tests/ui/method_no_resource.stderr create mode 100644 tests/ui/method_self.rs create mode 100644 tests/ui/method_self.stderr create mode 100644 tests/ui/method_too_few_args.rs create mode 100644 tests/ui/method_too_few_args.stderr create mode 100644 tests/ui/method_too_many_args.rs create mode 100644 tests/ui/method_too_many_args.stderr create mode 100644 tests/ui/method_unsafe.rs create mode 100644 tests/ui/method_unsafe.stderr create mode 100644 tests/util/mod.rs diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 7645df9..7e0dc00 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -122,13 +122,13 @@ pub fn change(attr : TokenStream, item : TokenStream) -> TokenStream } #[proc_macro_attribute] -pub fn delete_all(attr : TokenStream, item : TokenStream) -> TokenStream +pub fn remove_all(attr : TokenStream, item : TokenStream) -> TokenStream { expand_macro(attr, item, |attr, item| expand_method(Method::RemoveAll, attr, item)) } #[proc_macro_attribute] -pub fn delete(attr : TokenStream, item : TokenStream) -> TokenStream +pub fn remove(attr : TokenStream, item : TokenStream) -> TokenStream { expand_macro(attr, item, |attr, item| expand_method(Method::Remove, attr, item)) } diff --git a/derive/src/method.rs b/derive/src/method.rs index 789c50d..be19e0b 100644 --- a/derive/src/method.rs +++ b/derive/src/method.rs @@ -150,13 +150,18 @@ impl MethodArgumentType matches!(self, Self::AuthStatus(_) | Self::AuthStatusRef(_)) } - fn quote_ty(&self) -> Option + fn ty(&self) -> Option<&Type> { match self { - Self::MethodArg(ty) | Self::DatabaseConnection(ty) | Self::AuthStatus(ty) | Self::AuthStatusRef(ty) => Some(quote!(#ty)), + Self::MethodArg(ty) | Self::DatabaseConnection(ty) | Self::AuthStatus(ty) | Self::AuthStatusRef(ty) => Some(ty), _ => None } } + + fn quote_ty(&self) -> Option + { + self.ty().map(|ty| quote!(#ty)) + } } struct MethodArgument @@ -279,6 +284,10 @@ pub fn expand_method(method : Method, mut attrs : AttributeArgs, fun : ItemFn) - let krate = super::krate(); // parse attributes + if attrs.len() < 1 + { + return Err(Error::new(Span::call_site(), "Missing Resource struct. Example: #[read_all(MyResource)]")); + } let resource_path = match attrs.remove(0) { NestedMeta::Meta(Meta::Path(path)) => path, p => return Err(Error::new(p.span(), "Expected name of the Resource struct this method belongs to")) @@ -372,7 +381,7 @@ pub fn expand_method(method : Method, mut attrs : AttributeArgs, fun : ItemFn) - { if let Some(arg) = args.iter().find(|arg| (*arg).ty.is_state_ref()) { - return Err(Error::new(arg.span(), "async fn must not take &State as an argument as State is not Sync")); + return Err(Error::new(arg.span(), "async fn must not take &State as an argument as State is not Sync, consider boxing")); } block = quote!(#block.await); } diff --git a/example/src/main.rs b/example/src/main.rs index d300bd8..acb56d3 100644 --- a/example/src/main.rs +++ b/example/src/main.rs @@ -76,14 +76,14 @@ fn update(id : u64, body : User) info!("Change User {} to {}", id, body.username); } -#[delete_all(Users)] -fn delete_all() +#[remove_all(Users)] +fn remove_all() { info!("Delete all Users"); } -#[delete(Users)] -fn delete(id : u64) +#[remove(Users)] +fn remove(id : u64) { info!("Delete User {}", id); } diff --git a/tests/async_methods.rs b/tests/async_methods.rs new file mode 100644 index 0000000..42cbc25 --- /dev/null +++ b/tests/async_methods.rs @@ -0,0 +1,106 @@ +#[macro_use] extern crate gotham_derive; + +use gotham::{ + router::builder::*, + test::TestServer +}; +use gotham_restful::*; +use mime::{APPLICATION_JSON, TEXT_PLAIN}; +use serde::Deserialize; + +mod util { include!("util/mod.rs"); } +use util::{test_get_response, test_post_response, test_put_response, test_delete_response}; + + +#[derive(Resource)] +#[resource(read_all, read, search, create, change_all, change, remove_all, remove)] +struct FooResource; + +#[derive(Deserialize)] +#[cfg_attr(feature = "openapi", derive(OpenapiType))] +#[allow(dead_code)] +struct FooBody +{ + data : String +} + +#[derive(Deserialize, StateData, StaticResponseExtender)] +#[cfg_attr(feature = "openapi", derive(OpenapiType))] +#[allow(dead_code)] +struct FooSearch +{ + query : String +} + +const READ_ALL_RESPONSE : &[u8] = b"1ARwwSPVyOKpJKrYwqGgECPVWDl1BqajAAj7g7WJ3e"; +#[read_all(FooResource)] +async fn read_all() -> Raw<&'static [u8]> +{ + Raw::new(READ_ALL_RESPONSE, TEXT_PLAIN) +} + +const READ_RESPONSE : &[u8] = b"FEReHoeBKU17X2bBpVAd1iUvktFL43CDu0cFYHdaP9"; +#[read(FooResource)] +async fn read(_id : u64) -> Raw<&'static [u8]> +{ + Raw::new(READ_RESPONSE, TEXT_PLAIN) +} + +const SEARCH_RESPONSE : &[u8] = b"AWqcQUdBRHXKh3at4u79mdupOAfEbnTcx71ogCVF0E"; +#[search(FooResource)] +async fn search(_body : FooSearch) -> Raw<&'static [u8]> +{ + Raw::new(SEARCH_RESPONSE, TEXT_PLAIN) +} + +const CREATE_RESPONSE : &[u8] = b"y6POY7wOMAB0jBRBw0FJT7DOpUNbhmT8KdpQPLkI83"; +#[create(FooResource)] +async fn create(_body : FooBody) -> Raw<&'static [u8]> +{ + Raw::new(CREATE_RESPONSE, TEXT_PLAIN) +} + +const CHANGE_ALL_RESPONSE : &[u8] = b"QlbYg8gHE9OQvvk3yKjXJLTSXlIrg9mcqhfMXJmQkv"; +#[change_all(FooResource)] +async fn change_all(_body : FooBody) -> Raw<&'static [u8]> +{ + Raw::new(CHANGE_ALL_RESPONSE, TEXT_PLAIN) +} + +const CHANGE_RESPONSE : &[u8] = b"qGod55RUXkT1lgPO8h0uVM6l368O2S0GrwENZFFuRu"; +#[change(FooResource)] +async fn change(_id : u64, _body : FooBody) -> Raw<&'static [u8]> +{ + Raw::new(CHANGE_RESPONSE, TEXT_PLAIN) +} + +const REMOVE_ALL_RESPONSE : &[u8] = b"Y36kZ749MRk2Nem4BedJABOZiZWPLOtiwLfJlGTwm5"; +#[remove_all(FooResource)] +async fn remove_all() -> Raw<&'static [u8]> +{ + Raw::new(REMOVE_ALL_RESPONSE, TEXT_PLAIN) +} + +const REMOVE_RESPONSE : &[u8] = b"CwRzBrKErsVZ1N7yeNfjZuUn1MacvgBqk4uPOFfDDq"; +#[remove(FooResource)] +async fn remove(_id : u64) -> Raw<&'static [u8]> +{ + Raw::new(REMOVE_RESPONSE, TEXT_PLAIN) +} + +#[test] +fn async_methods() +{ + let server = TestServer::new(build_simple_router(|router| { + router.resource::("foo"); + })).unwrap(); + + test_get_response(&server, "http://localhost/foo", READ_ALL_RESPONSE); + test_get_response(&server, "http://localhost/foo/1", READ_RESPONSE); + test_get_response(&server, "http://localhost/foo/search?query=hello+world", SEARCH_RESPONSE); + test_post_response(&server, "http://localhost/foo", r#"{"data":"hello world"}"#, APPLICATION_JSON, CREATE_RESPONSE); + test_put_response(&server, "http://localhost/foo", r#"{"data":"hello world"}"#, APPLICATION_JSON, CHANGE_ALL_RESPONSE); + test_put_response(&server, "http://localhost/foo/1", r#"{"data":"hello world"}"#, APPLICATION_JSON, CHANGE_RESPONSE); + test_delete_response(&server, "http://localhost/foo", REMOVE_ALL_RESPONSE); + test_delete_response(&server, "http://localhost/foo/1", REMOVE_RESPONSE); +} diff --git a/tests/custom_request_body.rs b/tests/custom_request_body.rs index 5b108c7..95fa748 100644 --- a/tests/custom_request_body.rs +++ b/tests/custom_request_body.rs @@ -1,7 +1,3 @@ -mod custom_request_body -{ - - use gotham::{ hyper::header::CONTENT_TYPE, router::builder::*, @@ -10,6 +6,7 @@ use gotham::{ use gotham_restful::*; use mime::TEXT_PLAIN; + const RESPONSE : &[u8] = b"This is the only valid response."; #[derive(Resource)] @@ -30,7 +27,7 @@ fn create(body : Foo) -> Raw> { #[test] -fn test() +fn custom_request_body() { let server = TestServer::new(build_simple_router(|router| { router.resource::("foo"); @@ -44,6 +41,3 @@ fn test() let body : &[u8] = res.as_ref(); assert_eq!(body, RESPONSE); } - - -} diff --git a/tests/openapi_supports_scope.rs b/tests/openapi_supports_scope.rs index 02ba509..62228da 100644 --- a/tests/openapi_supports_scope.rs +++ b/tests/openapi_supports_scope.rs @@ -10,6 +10,11 @@ use gotham::{ use gotham_restful::*; use mime::TEXT_PLAIN; +#[allow(dead_code)] +mod util { include!("util/mod.rs"); } +use util::test_get_response; + + const RESPONSE : &[u8] = b"This is the only valid response."; #[derive(Resource)] @@ -23,13 +28,6 @@ fn read_all() -> Raw<&'static [u8]> } -fn test_response(server : &TestServer, path : &str) -{ - let res = server.client().get(path).perform().unwrap().read_body().unwrap(); - let body : &[u8] = res.as_ref(); - assert_eq!(body, RESPONSE); -} - #[test] fn test() { @@ -51,10 +49,10 @@ fn test() }); })).unwrap(); - test_response(&server, "http://localhost/foo1"); - test_response(&server, "http://localhost/bar/foo2"); - test_response(&server, "http://localhost/bar/baz/foo3"); - test_response(&server, "http://localhost/foo4"); + test_get_response(&server, "http://localhost/foo1", RESPONSE); + test_get_response(&server, "http://localhost/bar/foo2", RESPONSE); + test_get_response(&server, "http://localhost/bar/baz/foo3", RESPONSE); + test_get_response(&server, "http://localhost/foo4", RESPONSE); } diff --git a/tests/sync_methods.rs b/tests/sync_methods.rs new file mode 100644 index 0000000..a13ec19 --- /dev/null +++ b/tests/sync_methods.rs @@ -0,0 +1,106 @@ +#[macro_use] extern crate gotham_derive; + +use gotham::{ + router::builder::*, + test::TestServer +}; +use gotham_restful::*; +use mime::{APPLICATION_JSON, TEXT_PLAIN}; +use serde::Deserialize; + +mod util { include!("util/mod.rs"); } +use util::{test_get_response, test_post_response, test_put_response, test_delete_response}; + + +#[derive(Resource)] +#[resource(read_all, read, search, create, change_all, change, remove_all, remove)] +struct FooResource; + +#[derive(Deserialize)] +#[cfg_attr(feature = "openapi", derive(OpenapiType))] +#[allow(dead_code)] +struct FooBody +{ + data : String +} + +#[derive(Deserialize, StateData, StaticResponseExtender)] +#[cfg_attr(feature = "openapi", derive(OpenapiType))] +#[allow(dead_code)] +struct FooSearch +{ + query : String +} + +const READ_ALL_RESPONSE : &[u8] = b"1ARwwSPVyOKpJKrYwqGgECPVWDl1BqajAAj7g7WJ3e"; +#[read_all(FooResource)] +fn read_all() -> Raw<&'static [u8]> +{ + Raw::new(READ_ALL_RESPONSE, TEXT_PLAIN) +} + +const READ_RESPONSE : &[u8] = b"FEReHoeBKU17X2bBpVAd1iUvktFL43CDu0cFYHdaP9"; +#[read(FooResource)] +fn read(_id : u64) -> Raw<&'static [u8]> +{ + Raw::new(READ_RESPONSE, TEXT_PLAIN) +} + +const SEARCH_RESPONSE : &[u8] = b"AWqcQUdBRHXKh3at4u79mdupOAfEbnTcx71ogCVF0E"; +#[search(FooResource)] +fn search(_body : FooSearch) -> Raw<&'static [u8]> +{ + Raw::new(SEARCH_RESPONSE, TEXT_PLAIN) +} + +const CREATE_RESPONSE : &[u8] = b"y6POY7wOMAB0jBRBw0FJT7DOpUNbhmT8KdpQPLkI83"; +#[create(FooResource)] +fn create(_body : FooBody) -> Raw<&'static [u8]> +{ + Raw::new(CREATE_RESPONSE, TEXT_PLAIN) +} + +const CHANGE_ALL_RESPONSE : &[u8] = b"QlbYg8gHE9OQvvk3yKjXJLTSXlIrg9mcqhfMXJmQkv"; +#[change_all(FooResource)] +fn change_all(_body : FooBody) -> Raw<&'static [u8]> +{ + Raw::new(CHANGE_ALL_RESPONSE, TEXT_PLAIN) +} + +const CHANGE_RESPONSE : &[u8] = b"qGod55RUXkT1lgPO8h0uVM6l368O2S0GrwENZFFuRu"; +#[change(FooResource)] +fn change(_id : u64, _body : FooBody) -> Raw<&'static [u8]> +{ + Raw::new(CHANGE_RESPONSE, TEXT_PLAIN) +} + +const REMOVE_ALL_RESPONSE : &[u8] = b"Y36kZ749MRk2Nem4BedJABOZiZWPLOtiwLfJlGTwm5"; +#[remove_all(FooResource)] +fn remove_all() -> Raw<&'static [u8]> +{ + Raw::new(REMOVE_ALL_RESPONSE, TEXT_PLAIN) +} + +const REMOVE_RESPONSE : &[u8] = b"CwRzBrKErsVZ1N7yeNfjZuUn1MacvgBqk4uPOFfDDq"; +#[remove(FooResource)] +fn remove(_id : u64) -> Raw<&'static [u8]> +{ + Raw::new(REMOVE_RESPONSE, TEXT_PLAIN) +} + +#[test] +fn sync_methods() +{ + let server = TestServer::new(build_simple_router(|router| { + router.resource::("foo"); + })).unwrap(); + + test_get_response(&server, "http://localhost/foo", READ_ALL_RESPONSE); + test_get_response(&server, "http://localhost/foo/1", READ_RESPONSE); + test_get_response(&server, "http://localhost/foo/search?query=hello+world", SEARCH_RESPONSE); + test_post_response(&server, "http://localhost/foo", r#"{"data":"hello world"}"#, APPLICATION_JSON, CREATE_RESPONSE); + test_put_response(&server, "http://localhost/foo", r#"{"data":"hello world"}"#, APPLICATION_JSON, CHANGE_ALL_RESPONSE); + test_put_response(&server, "http://localhost/foo/1", r#"{"data":"hello world"}"#, APPLICATION_JSON, CHANGE_RESPONSE); + test_delete_response(&server, "http://localhost/foo", REMOVE_ALL_RESPONSE); + test_delete_response(&server, "http://localhost/foo/1", REMOVE_RESPONSE); +} diff --git a/tests/trybuild_ui.rs b/tests/trybuild_ui.rs index ac7adff..b791172 100644 --- a/tests/trybuild_ui.rs +++ b/tests/trybuild_ui.rs @@ -8,4 +8,11 @@ fn trybuild_ui() // always enabled t.compile_fail("tests/ui/from_body_enum.rs"); + t.compile_fail("tests/ui/method_async_state.rs"); + t.compile_fail("tests/ui/method_for_unknown_resource.rs"); + t.compile_fail("tests/ui/method_no_resource.rs"); + t.compile_fail("tests/ui/method_self.rs"); + t.compile_fail("tests/ui/method_too_few_args.rs"); + t.compile_fail("tests/ui/method_too_many_args.rs"); + t.compile_fail("tests/ui/method_unsafe.rs"); } diff --git a/tests/ui/method_async_state.rs b/tests/ui/method_async_state.rs new file mode 100644 index 0000000..66b9fc7 --- /dev/null +++ b/tests/ui/method_async_state.rs @@ -0,0 +1,15 @@ +#[macro_use] extern crate gotham_restful; +use gotham_restful::State; + +#[derive(Resource)] +#[resource(read_all)] +struct FooResource; + +#[read_all(FooResource)] +async fn read_all(state : &State) +{ +} + +fn main() +{ +} diff --git a/tests/ui/method_async_state.stderr b/tests/ui/method_async_state.stderr new file mode 100644 index 0000000..5c02836 --- /dev/null +++ b/tests/ui/method_async_state.stderr @@ -0,0 +1,21 @@ +error: async fn must not take &State as an argument as State is not Sync, consider boxing + --> $DIR/method_async_state.rs:9:19 + | +9 | async fn read_all(state : &State) + | ^^^^^ + +error[E0433]: failed to resolve: use of undeclared type or module `_gotham_restful_resource_foo_resource_method_read_all` + --> $DIR/method_async_state.rs:4:10 + | +4 | #[derive(Resource)] + | ^^^^^^^^ use of undeclared type or module `_gotham_restful_resource_foo_resource_method_read_all` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: unused import: `gotham_restful::State` + --> $DIR/method_async_state.rs:2:5 + | +2 | use gotham_restful::State; + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unused_imports)]` on by default diff --git a/tests/ui/method_for_unknown_resource.rs b/tests/ui/method_for_unknown_resource.rs new file mode 100644 index 0000000..162dc94 --- /dev/null +++ b/tests/ui/method_for_unknown_resource.rs @@ -0,0 +1,10 @@ +#[macro_use] extern crate gotham_restful; + +#[read_all(UnknownResource)] +fn read_all() +{ +} + +fn main() +{ +} diff --git a/tests/ui/method_for_unknown_resource.stderr b/tests/ui/method_for_unknown_resource.stderr new file mode 100644 index 0000000..1e10d24 --- /dev/null +++ b/tests/ui/method_for_unknown_resource.stderr @@ -0,0 +1,5 @@ +error[E0412]: cannot find type `UnknownResource` in this scope + --> $DIR/method_for_unknown_resource.rs:3:12 + | +3 | #[read_all(UnknownResource)] + | ^^^^^^^^^^^^^^^ not found in this scope diff --git a/tests/ui/method_no_resource.rs b/tests/ui/method_no_resource.rs new file mode 100644 index 0000000..f0232b7 --- /dev/null +++ b/tests/ui/method_no_resource.rs @@ -0,0 +1,14 @@ +#[macro_use] extern crate gotham_restful; + +#[derive(Resource)] +#[resource(read_all)] +struct FooResource; + +#[read_all] +fn read_all() +{ +} + +fn main() +{ +} diff --git a/tests/ui/method_no_resource.stderr b/tests/ui/method_no_resource.stderr new file mode 100644 index 0000000..d4bc1c4 --- /dev/null +++ b/tests/ui/method_no_resource.stderr @@ -0,0 +1,15 @@ +error: Missing Resource struct. Example: #[read_all(MyResource)] + --> $DIR/method_no_resource.rs:7:1 + | +7 | #[read_all] + | ^^^^^^^^^^^ + | + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0433]: failed to resolve: use of undeclared type or module `_gotham_restful_resource_foo_resource_method_read_all` + --> $DIR/method_no_resource.rs:3:10 + | +3 | #[derive(Resource)] + | ^^^^^^^^ use of undeclared type or module `_gotham_restful_resource_foo_resource_method_read_all` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/method_self.rs b/tests/ui/method_self.rs new file mode 100644 index 0000000..3b19b11 --- /dev/null +++ b/tests/ui/method_self.rs @@ -0,0 +1,14 @@ +#[macro_use] extern crate gotham_restful; + +#[derive(Resource)] +#[resource(read_all)] +struct FooResource; + +#[read_all(FooResource)] +fn read_all(self) +{ +} + +fn main() +{ +} diff --git a/tests/ui/method_self.stderr b/tests/ui/method_self.stderr new file mode 100644 index 0000000..d4fea5f --- /dev/null +++ b/tests/ui/method_self.stderr @@ -0,0 +1,13 @@ +error: Didn't expect self parameter + --> $DIR/method_self.rs:8:13 + | +8 | fn read_all(self) + | ^^^^ + +error[E0433]: failed to resolve: use of undeclared type or module `_gotham_restful_resource_foo_resource_method_read_all` + --> $DIR/method_self.rs:3:10 + | +3 | #[derive(Resource)] + | ^^^^^^^^ use of undeclared type or module `_gotham_restful_resource_foo_resource_method_read_all` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/method_too_few_args.rs b/tests/ui/method_too_few_args.rs new file mode 100644 index 0000000..6f0309e --- /dev/null +++ b/tests/ui/method_too_few_args.rs @@ -0,0 +1,14 @@ +#[macro_use] extern crate gotham_restful; + +#[derive(Resource)] +#[resource(read)] +struct FooResource; + +#[read(FooResource)] +fn read() +{ +} + +fn main() +{ +} diff --git a/tests/ui/method_too_few_args.stderr b/tests/ui/method_too_few_args.stderr new file mode 100644 index 0000000..d8daeab --- /dev/null +++ b/tests/ui/method_too_few_args.stderr @@ -0,0 +1,13 @@ +error: Too few arguments + --> $DIR/method_too_few_args.rs:8:4 + | +8 | fn read() + | ^^^^ + +error[E0433]: failed to resolve: use of undeclared type or module `_gotham_restful_resource_foo_resource_method_read` + --> $DIR/method_too_few_args.rs:3:10 + | +3 | #[derive(Resource)] + | ^^^^^^^^ use of undeclared type or module `_gotham_restful_resource_foo_resource_method_read` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/method_too_many_args.rs b/tests/ui/method_too_many_args.rs new file mode 100644 index 0000000..5ae83eb --- /dev/null +++ b/tests/ui/method_too_many_args.rs @@ -0,0 +1,14 @@ +#[macro_use] extern crate gotham_restful; + +#[derive(Resource)] +#[resource(read_all)] +struct FooResource; + +#[read_all(FooResource)] +fn read_all(_id : u64) +{ +} + +fn main() +{ +} diff --git a/tests/ui/method_too_many_args.stderr b/tests/ui/method_too_many_args.stderr new file mode 100644 index 0000000..3f8bd39 --- /dev/null +++ b/tests/ui/method_too_many_args.stderr @@ -0,0 +1,13 @@ +error: Too many arguments + --> $DIR/method_too_many_args.rs:8:13 + | +8 | fn read_all(_id : u64) + | ^^^ + +error[E0433]: failed to resolve: use of undeclared type or module `_gotham_restful_resource_foo_resource_method_read_all` + --> $DIR/method_too_many_args.rs:3:10 + | +3 | #[derive(Resource)] + | ^^^^^^^^ use of undeclared type or module `_gotham_restful_resource_foo_resource_method_read_all` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/method_unsafe.rs b/tests/ui/method_unsafe.rs new file mode 100644 index 0000000..65a76bc --- /dev/null +++ b/tests/ui/method_unsafe.rs @@ -0,0 +1,14 @@ +#[macro_use] extern crate gotham_restful; + +#[derive(Resource)] +#[resource(read_all)] +struct FooResource; + +#[read_all(FooResource)] +unsafe fn read_all() +{ +} + +fn main() +{ +} diff --git a/tests/ui/method_unsafe.stderr b/tests/ui/method_unsafe.stderr new file mode 100644 index 0000000..aeb104e --- /dev/null +++ b/tests/ui/method_unsafe.stderr @@ -0,0 +1,13 @@ +error: Resource methods must not be unsafe + --> $DIR/method_unsafe.rs:8:1 + | +8 | unsafe fn read_all() + | ^^^^^^ + +error[E0433]: failed to resolve: use of undeclared type or module `_gotham_restful_resource_foo_resource_method_read_all` + --> $DIR/method_unsafe.rs:3:10 + | +3 | #[derive(Resource)] + | ^^^^^^^^ use of undeclared type or module `_gotham_restful_resource_foo_resource_method_read_all` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/util/mod.rs b/tests/util/mod.rs new file mode 100644 index 0000000..e09a37f --- /dev/null +++ b/tests/util/mod.rs @@ -0,0 +1,37 @@ +use gotham::{ + hyper::Body, + test::TestServer +}; +use mime::Mime; + +pub fn test_get_response(server : &TestServer, path : &str, expected : &[u8]) +{ + let res = server.client().get(path).perform().unwrap().read_body().unwrap(); + let body : &[u8] = res.as_ref(); + assert_eq!(body, expected); +} + +pub fn test_post_response(server : &TestServer, path : &str, body : B, mime : Mime, expected : &[u8]) +where + B : Into +{ + let res = server.client().post(path, body, mime).perform().unwrap().read_body().unwrap(); + let body : &[u8] = res.as_ref(); + assert_eq!(body, expected); +} + +pub fn test_put_response(server : &TestServer, path : &str, body : B, mime : Mime, expected : &[u8]) +where + B : Into +{ + let res = server.client().put(path, body, mime).perform().unwrap().read_body().unwrap(); + let body : &[u8] = res.as_ref(); + assert_eq!(body, expected); +} + +pub fn test_delete_response(server : &TestServer, path : &str, expected : &[u8]) +{ + let res = server.client().delete(path).perform().unwrap().read_body().unwrap(); + let body : &[u8] = res.as_ref(); + assert_eq!(body, expected); +}