Fixed unchecked unwrap. Added codegen tests.

This commit is contained in:
Sergio Benitez 2016-09-08 17:09:35 -07:00
parent f259593727
commit 5915c69f39
9 changed files with 101 additions and 9 deletions

9
codegen_tests/Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "codegen_tests"
version = "0.1.0"
authors = ["Sergio Benitez <sb@sergio.bz>"]
[dev-dependencies]
compiletest-rs = "*"
rocket = "../lib"
rocket_macros = "../macros"

View File

@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

View File

@ -10,3 +10,6 @@ plugin = true
rocket = { path = "../lib/" }
log = "*"
env_logger = "*"
[dev-dependencies]
compiletest_rs = "*"

View File

@ -78,6 +78,11 @@ impl RouteGenerateExt for RouteParams {
}
let arg = arg.unwrap();
if arg.ident().is_none() {
ecx.span_err(arg.pat.span, "argument names must be identifiers");
return None;
};
let name = arg.ident().unwrap().prepend(PARAM_PREFIX);
let ty = strip_ty_lifetimes(arg.ty.clone());
Some(quote_stmt!(ecx,
@ -147,12 +152,14 @@ impl RouteGenerateExt for RouteParams {
// A from_request parameter is one that isn't declared, form, or query.
let from_request = |a: &&Arg| {
!declared_set.contains(&*a.name().unwrap())
&& self.form_param.as_ref().map_or(true, |p| {
!a.named(&p.value().name)
}) && self.query_param.as_ref().map_or(true, |p| {
!a.named(&p.node.name)
})
a.name().map_or(false, |name| {
!declared_set.contains(name)
&& self.form_param.as_ref().map_or(true, |p| {
!a.named(&p.value().name)
}) && self.query_param.as_ref().map_or(true, |p| {
!a.named(&p.node.name)
})
})
};
// Generate the code for `form_request` parameters.
@ -173,9 +180,10 @@ impl RouteGenerateExt for RouteParams {
}
fn generate_fn_arguments(&self, ecx: &ExtCtxt) -> Vec<TokenTree> {
let args = self.annotated_fn.decl().inputs.iter().map(|a| {
a.ident().expect("function decl pat -> ident").prepend(PARAM_PREFIX)
}).collect::<Vec<Ident>>();
let args = self.annotated_fn.decl().inputs.iter()
.filter_map(|a| a.ident())
.map(|ident| ident.prepend(PARAM_PREFIX))
.collect::<Vec<Ident>>();
sep_by_tok(ecx, &args, token::Comma)
}

View File

@ -0,0 +1,7 @@
#![feature(plugin)]
#![plugin(rocket_macros)]
#[get("/<name>")] //~ ERROR 'name' is declared
fn get(_: &str) -> &'static str { "hi" } //~ ERROR isn't in the function
fn main() { }

View File

@ -0,0 +1,17 @@
#![feature(plugin)]
#![plugin(rocket_macros)]
#[get("/<param>")] //~ ERROR declared
fn get() { } //~ ERROR isn't in the function signature
#[get("/<a>")] //~ ERROR declared
fn get2() { } //~ ERROR isn't in the function signature
#[get("/a/b/c/<a>/<b>")]
//~^ ERROR 'a' is declared
//~^^ ERROR 'b' is declared
fn get32() { }
//~^ ERROR isn't in the function signature
//~^^ ERROR isn't in the function signature
fn main() { }

View File

@ -0,0 +1,11 @@
#![feature(plugin)]
#![plugin(rocket_macros)]
extern crate rocket;
#[get("")]
fn get() -> &'static str { "hi" }
fn main() {
let _ = routes![get];
}

View File

@ -0,0 +1,14 @@
#![feature(plugin)]
#![plugin(rocket_macros)]
extern crate rocket;
#[get("/<todo>")]
fn todo(todo: &str) -> &str {
todo
}
fn main() {
let _ = routes![todo];
}

20
macros/tests/tests.rs Normal file
View File

@ -0,0 +1,20 @@
extern crate compiletest_rs as compiletest;
use std::path::PathBuf;
fn run_mode(mode: &'static str) {
let mut config = compiletest::default_config();
let cfg_mode = mode.parse().ok().expect("Invalid mode");
config.mode = cfg_mode;
config.src_base = PathBuf::from(format!("tests/{}", mode));
config.target_rustcflags = Some("-L ../target/debug/ -L ../target/debug/deps/".to_owned());
compiletest::run_tests(&config);
}
#[test]
fn compile_test() {
run_mode("compile-fail");
run_mode("run-pass");
}