add trybuild tests

This commit is contained in:
Rob Ede 2023-02-26 02:57:21 +00:00
parent facc43e5ad
commit 12d90d5762
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
17 changed files with 193 additions and 16 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "actix-multipart-derive"
version = "0.4.0"
version = "0.5.0"
authors = ["Jacob Halsey <jacob@jhalsey.com>"]
description = "Multipart form derive macro for Actix Web"
keywords = ["http", "web", "framework", "async", "futures"]
@ -20,5 +20,7 @@ quote = "1"
syn = "1"
[dev-dependencies]
actix-multipart = "0.4"
actix-multipart = "0.5"
actix-web = "4"
rustversion = "1"
trybuild = "1"

View File

@ -1,3 +1,3 @@
# actix-multipart-derive
> The derive macro implementation for actix-multipart
> The derive macro implementation for actix-multipart.

View File

@ -1,4 +1,6 @@
//! Multipart form derive macro for Actix Web.
//!
//! See [`macro@MultipartForm`] for usage examples.
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible)]
@ -57,13 +59,13 @@ struct ParsedField<'t> {
/// Each field type should implement the `FieldReader` trait:
///
/// ```
/// use actix_multipart::form::{tempfile::Tempfile, text::Text, MultipartForm};
/// use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
///
/// #[derive(MultipartForm)]
/// struct ImageUpload {
/// description: Text<String>,
/// timestamp: Text<i64>,
/// image: Tempfile,
/// image: TempFile,
/// }
/// ```
///
@ -75,12 +77,12 @@ struct ParsedField<'t> {
/// name](https://www.rfc-editor.org/rfc/rfc7578#section-4.3).
///
/// ```
/// use actix_multipart::form::{tempfile::Tempfile, text::Text, MultipartForm};
/// use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
///
/// #[derive(MultipartForm)]
/// struct Form {
/// category: Option<Text<String>>,
/// files: Vec<Tempfile>,
/// files: Vec<TempFile>,
/// }
/// ```
///
@ -89,12 +91,12 @@ struct ParsedField<'t> {
/// You can use the `#[multipart(rename = "foo")]` attribute to receive a field by a different name.
///
/// ```
/// use actix_multipart::form::{tempfile::Tempfile, MultipartForm};
/// use actix_multipart::form::{tempfile::TempFile, MultipartForm};
///
/// #[derive(MultipartForm)]
/// struct Form {
/// #[multipart(rename = "files[]")]
/// files: Vec<Tempfile>,
/// files: Vec<TempFile>,
/// }
/// ```
///
@ -106,7 +108,7 @@ struct ParsedField<'t> {
/// Note: the form is also subject to the global limits configured using `MultipartFormConfig`.
///
/// ```
/// use actix_multipart::form::{tempfile::Tempfile, text::Text, MultipartForm};
/// use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
///
/// #[derive(MultipartForm)]
/// struct Form {
@ -114,7 +116,7 @@ struct ParsedField<'t> {
/// description: Text<String>,
///
/// #[multipart(limit = "512 MiB")]
/// files: Vec<Tempfile>,
/// files: Vec<TempFile>,
/// }
/// ```
///
@ -124,8 +126,7 @@ struct ParsedField<'t> {
/// `#[multipart(deny_unknown_fields)]` attribute:
///
/// ```
/// use actix_multipart::form::MultipartForm;
///
/// # use actix_multipart::form::MultipartForm;
/// #[derive(MultipartForm)]
/// #[multipart(deny_unknown_fields)]
/// struct Form { }

View File

@ -0,0 +1,16 @@
#[rustversion::stable(1.59)] // MSRV
#[test]
fn compile_macros() {
let t = trybuild::TestCases::new();
t.pass("tests/trybuild/all-required.rs");
t.pass("tests/trybuild/optional-and-list.rs");
t.pass("tests/trybuild/rename.rs");
t.pass("tests/trybuild/deny-unknown.rs");
t.pass("tests/trybuild/deny-duplicates.rs");
t.compile_fail("tests/trybuild/deny-parse-fail.rs");
t.pass("tests/trybuild/size-limits.rs");
t.compile_fail("tests/trybuild/size-limit-parse-fail.rs");
}

View File

@ -0,0 +1,19 @@
use actix_web::{web, App, Responder};
use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
#[derive(Debug, MultipartForm)]
struct ImageUpload {
description: Text<String>,
timestamp: Text<i64>,
image: TempFile,
}
async fn handler(_form: MultipartForm<ImageUpload>) -> impl Responder {
"Hello World!"
}
#[actix_web::main]
async fn main() {
App::new().default_service(web::to(handler));
}

View File

@ -0,0 +1,16 @@
use actix_web::{web, App, Responder};
use actix_multipart::form::MultipartForm;
#[derive(MultipartForm)]
#[multipart(duplicate_field = "deny")]
struct Form {}
async fn handler(_form: MultipartForm<Form>) -> impl Responder {
"Hello World!"
}
#[actix_web::main]
async fn main() {
App::new().default_service(web::to(handler));
}

View File

@ -0,0 +1,7 @@
use actix_multipart::form::MultipartForm;
#[derive(MultipartForm)]
#[multipart(duplicate_field = "no")]
struct Form {}
fn main() {}

View File

@ -0,0 +1,5 @@
error: Unknown literal value `no`
--> tests/trybuild/deny-parse-fail.rs:4:31
|
4 | #[multipart(duplicate_field = "no")]
| ^^^^

View File

@ -0,0 +1,16 @@
use actix_web::{web, App, Responder};
use actix_multipart::form::MultipartForm;
#[derive(MultipartForm)]
#[multipart(deny_unknown_fields)]
struct Form {}
async fn handler(_form: MultipartForm<Form>) -> impl Responder {
"Hello World!"
}
#[actix_web::main]
async fn main() {
App::new().default_service(web::to(handler));
}

View File

@ -0,0 +1,18 @@
use actix_web::{web, App, Responder};
use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
#[derive(MultipartForm)]
struct Form {
category: Option<Text<String>>,
files: Vec<TempFile>,
}
async fn handler(_form: MultipartForm<Form>) -> impl Responder {
"Hello World!"
}
#[actix_web::main]
async fn main() {
App::new().default_service(web::to(handler));
}

View File

@ -0,0 +1,18 @@
use actix_web::{web, App, Responder};
use actix_multipart::form::{tempfile::TempFile, MultipartForm};
#[derive(MultipartForm)]
struct Form {
#[multipart(rename = "files[]")]
files: Vec<TempFile>,
}
async fn handler(_form: MultipartForm<Form>) -> impl Responder {
"Hello World!"
}
#[actix_web::main]
async fn main() {
App::new().default_service(web::to(handler));
}

View File

@ -0,0 +1,21 @@
use actix_multipart::form::{text::Text, MultipartForm};
#[derive(MultipartForm)]
struct Form {
#[multipart(limit = "2 bytes")]
description: Text<String>,
}
#[derive(MultipartForm)]
struct Form2 {
#[multipart(limit = "2 megabytes")]
description: Text<String>,
}
#[derive(MultipartForm)]
struct Form3 {
#[multipart(limit = "four meters")]
description: Text<String>,
}
fn main() {}

View File

@ -0,0 +1,17 @@
error: Could not parse size limit `2 bytes`: invalid digit found in string
--> tests/trybuild/size-limit-parse-fail.rs:6:5
|
6 | description: Text<String>,
| ^^^^^^^^^^^
error: Could not parse size limit `2 megabytes`: invalid digit found in string
--> tests/trybuild/size-limit-parse-fail.rs:12:5
|
12 | description: Text<String>,
| ^^^^^^^^^^^
error: Could not parse size limit `four meters`: invalid digit found in string
--> tests/trybuild/size-limit-parse-fail.rs:18:5
|
18 | description: Text<String>,
| ^^^^^^^^^^^

View File

@ -0,0 +1,21 @@
use actix_web::{web, App, Responder};
use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
#[derive(MultipartForm)]
struct Form {
#[multipart(limit = "2 KiB")]
description: Text<String>,
#[multipart(limit = "512 MiB")]
files: Vec<TempFile>,
}
async fn handler(_form: MultipartForm<Form>) -> impl Responder {
"Hello World!"
}
#[actix_web::main]
async fn main() {
App::new().default_service(web::to(handler));
}

View File

@ -26,7 +26,7 @@ name = "actix_multipart"
path = "src/lib.rs"
[dependencies]
actix-multipart-derive = { version = "=0.4.0", optional = true }
actix-multipart-derive = { version = "=0.5.0", optional = true }
actix-utils = "3"
actix-web = { version = "4", default-features = false }

View File

@ -103,7 +103,7 @@ actix-test = { version = "0.1", features = ["openssl", "rustls"] }
awc = { version = "3", features = ["openssl"] }
brotli = "3.3.3"
const-str = "0.4"
const-str = "0.3"
criterion = { version = "0.4", features = ["html_reports"] }
env_logger = "0.9"
flate2 = "1.0.13"

View File

@ -99,7 +99,7 @@ actix-utils = "3"
actix-web = { version = "4", features = ["openssl"] }
brotli = "3.3.3"
const-str = "0.4"
const-str = "0.3"
env_logger = "0.9"
flate2 = "1.0.13"
futures-util = { version = "0.3.17", default-features = false }