Skip to content

Commit e3e14c4

Browse files
committed
Add testcase
1 parent 19ff69d commit e3e14c4

File tree

4 files changed

+175
-9
lines changed

4 files changed

+175
-9
lines changed

crates/vespera_macro/src/lib.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -283,12 +283,7 @@ pub fn export_app(input: TokenStream) -> TokenStream {
283283
.lock()
284284
.unwrap_or_else(std::sync::PoisonError::into_inner);
285285
let Ok(manifest_dir) = std::env::var("CARGO_MANIFEST_DIR") else {
286-
return syn::Error::new(
287-
proc_macro2::Span::call_site(),
288-
"export_app! macro: CARGO_MANIFEST_DIR is not set. This macro must be used within a cargo build.",
289-
)
290-
.to_compile_error()
291-
.into();
286+
return syn::Error::new(proc_macro2::Span::call_site(), "export_app! macro: CARGO_MANIFEST_DIR is not set. This macro must be used within a cargo build.").to_compile_error().into();
292287
};
293288

294289
match process_export_app(&name, &folder_name, &schema_storage, &manifest_dir) {

crates/vespera_macro/src/openapi_generator.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,98 @@ pub fn get_user() -> User {
13461346
assert!(value.is_none());
13471347
}
13481348

1349+
#[test]
1350+
fn test_build_path_items_unknown_http_method() {
1351+
// Test lines 131-134: route with unknown HTTP method is skipped
1352+
let temp_dir = TempDir::new().expect("Failed to create temp dir");
1353+
1354+
let route_content = r#"
1355+
pub fn get_users() -> String {
1356+
"users".to_string()
1357+
}
1358+
"#;
1359+
let route_file = create_temp_file(&temp_dir, "users.rs", route_content);
1360+
1361+
let mut metadata = CollectedMetadata::new();
1362+
metadata.routes.push(RouteMetadata {
1363+
method: "INVALID".to_string(),
1364+
path: "/users".to_string(),
1365+
function_name: "get_users".to_string(),
1366+
module_path: "test::users".to_string(),
1367+
file_path: route_file.to_string_lossy().to_string(),
1368+
signature: "fn get_users() -> String".to_string(),
1369+
error_status: None,
1370+
tags: None,
1371+
description: None,
1372+
});
1373+
1374+
let doc = generate_openapi_doc_with_metadata(None, None, None, &metadata);
1375+
1376+
// Route with unknown HTTP method should be skipped entirely
1377+
assert!(
1378+
doc.paths.is_empty(),
1379+
"Route with unknown HTTP method should be skipped"
1380+
);
1381+
}
1382+
1383+
#[test]
1384+
fn test_build_path_items_unknown_method_skipped_valid_kept() {
1385+
// Test that unknown methods are skipped while valid routes are kept
1386+
let temp_dir = TempDir::new().expect("Failed to create temp dir");
1387+
1388+
let route_content = r#"
1389+
pub fn get_users() -> String {
1390+
"users".to_string()
1391+
}
1392+
1393+
pub fn create_users() -> String {
1394+
"created".to_string()
1395+
}
1396+
"#;
1397+
let route_file = create_temp_file(&temp_dir, "users.rs", route_content);
1398+
let file_path = route_file.to_string_lossy().to_string();
1399+
1400+
let mut metadata = CollectedMetadata::new();
1401+
// Invalid method route
1402+
metadata.routes.push(RouteMetadata {
1403+
method: "CONNECT".to_string(),
1404+
path: "/users".to_string(),
1405+
function_name: "get_users".to_string(),
1406+
module_path: "test::users".to_string(),
1407+
file_path: file_path.clone(),
1408+
signature: "fn get_users() -> String".to_string(),
1409+
error_status: None,
1410+
tags: None,
1411+
description: None,
1412+
});
1413+
// Valid method route
1414+
metadata.routes.push(RouteMetadata {
1415+
method: "POST".to_string(),
1416+
path: "/users".to_string(),
1417+
function_name: "create_users".to_string(),
1418+
module_path: "test::users".to_string(),
1419+
file_path,
1420+
signature: "fn create_users() -> String".to_string(),
1421+
error_status: None,
1422+
tags: None,
1423+
description: None,
1424+
});
1425+
1426+
let doc = generate_openapi_doc_with_metadata(None, None, None, &metadata);
1427+
1428+
// Only the valid POST route should appear
1429+
assert_eq!(doc.paths.len(), 1);
1430+
let path_item = doc.paths.get("/users").unwrap();
1431+
assert!(
1432+
path_item.post.is_some(),
1433+
"Valid POST route should be present"
1434+
);
1435+
assert!(
1436+
path_item.get.is_none(),
1437+
"Invalid method route should be skipped"
1438+
);
1439+
}
1440+
13491441
#[test]
13501442
fn test_generate_openapi_with_unparseable_definition() {
13511443
// Test line 42: syn::parse_str fails with invalid Rust syntax

crates/vespera_macro/src/router_codegen.rs

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,9 @@
3636
use proc_macro2::Span;
3737
use quote::quote;
3838
use syn::{
39-
bracketed,
39+
LitStr, bracketed,
4040
parse::{Parse, ParseStream},
4141
punctuated::Punctuated,
42-
LitStr,
4342
};
4443
use vespera_core::{openapi::Server, route::HttpMethod};
4544

@@ -1262,6 +1261,87 @@ pub fn get_users() -> String {
12621261
assert!(result.is_err());
12631262
}
12641263

1264+
#[test]
1265+
fn test_generate_router_code_unknown_http_method() {
1266+
// Test lines 337-340: route with unknown HTTP method is skipped in router codegen
1267+
let mut metadata = CollectedMetadata {
1268+
routes: Vec::new(),
1269+
structs: Vec::new(),
1270+
};
1271+
metadata.routes.push(crate::metadata::RouteMetadata {
1272+
method: "INVALID".to_string(),
1273+
path: "/users".to_string(),
1274+
function_name: "get_users".to_string(),
1275+
module_path: "routes::users".to_string(),
1276+
file_path: "dummy.rs".to_string(),
1277+
signature: "fn get_users() -> String".to_string(),
1278+
error_status: None,
1279+
tags: None,
1280+
description: None,
1281+
});
1282+
1283+
let result = generate_router_code(&metadata, None, None, &[]);
1284+
let code = result.to_string();
1285+
1286+
// Router should be generated but without any route calls
1287+
assert!(
1288+
code.contains("Router") && code.contains("new"),
1289+
"Code should contain Router::new(), got: {code}"
1290+
);
1291+
assert!(
1292+
!code.contains(". route ("),
1293+
"Route with unknown HTTP method should be skipped, got: {code}"
1294+
);
1295+
}
1296+
1297+
#[test]
1298+
fn test_generate_router_code_unknown_method_skipped_valid_kept() {
1299+
// Test that unknown methods are skipped while valid routes are still generated
1300+
let temp_dir = TempDir::new().expect("Failed to create temp dir");
1301+
let folder_name = "routes";
1302+
1303+
create_temp_file(
1304+
&temp_dir,
1305+
"users.rs",
1306+
r#"
1307+
#[route(get)]
1308+
pub fn get_users() -> String {
1309+
"users".to_string()
1310+
}
1311+
"#,
1312+
);
1313+
1314+
let mut metadata = collect_metadata(temp_dir.path(), folder_name).unwrap();
1315+
// Inject an additional route with invalid method
1316+
metadata.routes.push(crate::metadata::RouteMetadata {
1317+
method: "CONNECT".to_string(),
1318+
path: "/invalid".to_string(),
1319+
function_name: "connect_handler".to_string(),
1320+
module_path: "routes::invalid".to_string(),
1321+
file_path: "dummy.rs".to_string(),
1322+
signature: "fn connect_handler() -> String".to_string(),
1323+
error_status: None,
1324+
tags: None,
1325+
description: None,
1326+
});
1327+
1328+
let result = generate_router_code(&metadata, None, None, &[]);
1329+
let code = result.to_string();
1330+
1331+
// Valid route should be present
1332+
assert!(
1333+
code.contains("get_users"),
1334+
"Valid route should be present, got: {code}"
1335+
);
1336+
// Invalid route should be skipped
1337+
assert!(
1338+
!code.contains("connect_handler"),
1339+
"Invalid method route should be skipped, got: {code}"
1340+
);
1341+
1342+
drop(temp_dir);
1343+
}
1344+
12651345
#[test]
12661346
fn test_auto_router_input_parse_invalid_token() {
12671347
// Test line 149: neither ident nor string literal triggers lookahead error

crates/vespera_macro/src/schema_impl.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ mod tests {
190190
assert_eq!(metadata.name, "Container");
191191
}
192192

193-
194193
#[test]
195194
fn test_extract_schema_name_attr_non_name_meta_key() {
196195
// #[schema(other = "foo")] — has schema attr but no "name" key

0 commit comments

Comments
 (0)