Skip to content

Commit 5d4a621

Browse files
committed
Add testcase
1 parent 2b7102b commit 5d4a621

3 files changed

Lines changed: 1035 additions & 34 deletions

File tree

crates/vespera_macro/src/schema_macro/file_lookup.rs

Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,4 +1100,319 @@ pub const NOT_STRUCT: i32 = 1;
11001100
"Module path should contain 'special_item'"
11011101
);
11021102
}
1103+
1104+
// ============================================================
1105+
// Coverage tests for find_fk_column_from_target_entity (lines 287-333)
1106+
// ============================================================
1107+
1108+
#[test]
1109+
#[serial]
1110+
fn test_find_fk_column_from_target_entity_success() {
1111+
// Tests: Full success path - find FK column from target entity
1112+
// Covers lines 287, 291-292, 296, 298, 305, 307-309, 312, 315-317, 320-323, 325
1113+
let temp_dir = TempDir::new().unwrap();
1114+
let src_dir = temp_dir.path().join("src");
1115+
let models_dir = src_dir.join("models");
1116+
std::fs::create_dir_all(&models_dir).unwrap();
1117+
1118+
// Create notification.rs with a BelongsTo relation that has relation_enum matching via_rel
1119+
let notification_model = r#"
1120+
pub struct Model {
1121+
pub id: i32,
1122+
pub message: String,
1123+
pub target_user_id: i32,
1124+
#[sea_orm(belongs_to = "super::user::Entity", from = "target_user_id", to = "id", relation_enum = "TargetUser")]
1125+
pub target_user: BelongsTo<super::user::Entity>,
1126+
}
1127+
"#;
1128+
std::fs::write(models_dir.join("notification.rs"), notification_model).unwrap();
1129+
1130+
let original = std::env::var("CARGO_MANIFEST_DIR").ok();
1131+
unsafe { std::env::set_var("CARGO_MANIFEST_DIR", temp_dir.path()) };
1132+
1133+
let result =
1134+
find_fk_column_from_target_entity("crate::models::notification::Schema", "TargetUser");
1135+
1136+
unsafe {
1137+
if let Some(dir) = original {
1138+
std::env::set_var("CARGO_MANIFEST_DIR", dir);
1139+
} else {
1140+
std::env::remove_var("CARGO_MANIFEST_DIR");
1141+
}
1142+
}
1143+
1144+
assert_eq!(
1145+
result,
1146+
Some("target_user_id".to_string()),
1147+
"Should find FK column 'target_user_id'"
1148+
);
1149+
}
1150+
1151+
#[test]
1152+
#[serial]
1153+
fn test_find_fk_column_from_target_entity_mod_rs() {
1154+
// Tests: Find FK column from mod.rs file (line 305 second path)
1155+
let temp_dir = TempDir::new().unwrap();
1156+
let src_dir = temp_dir.path().join("src");
1157+
let models_dir = src_dir.join("models").join("notification");
1158+
std::fs::create_dir_all(&models_dir).unwrap();
1159+
1160+
let notification_model = r#"
1161+
pub struct Model {
1162+
pub id: i32,
1163+
pub sender_id: i32,
1164+
#[sea_orm(belongs_to = "super::super::user::Entity", from = "sender_id", to = "id", relation_enum = "Sender")]
1165+
pub sender: BelongsTo<super::super::user::Entity>,
1166+
}
1167+
"#;
1168+
std::fs::write(models_dir.join("mod.rs"), notification_model).unwrap();
1169+
1170+
let original = std::env::var("CARGO_MANIFEST_DIR").ok();
1171+
unsafe { std::env::set_var("CARGO_MANIFEST_DIR", temp_dir.path()) };
1172+
1173+
let result =
1174+
find_fk_column_from_target_entity("crate::models::notification::Schema", "Sender");
1175+
1176+
unsafe {
1177+
if let Some(dir) = original {
1178+
std::env::set_var("CARGO_MANIFEST_DIR", dir);
1179+
} else {
1180+
std::env::remove_var("CARGO_MANIFEST_DIR");
1181+
}
1182+
}
1183+
1184+
assert_eq!(
1185+
result,
1186+
Some("sender_id".to_string()),
1187+
"Should find FK column from mod.rs"
1188+
);
1189+
}
1190+
1191+
#[test]
1192+
#[serial]
1193+
fn test_find_fk_column_from_target_entity_empty_module_segments() {
1194+
// Tests lines 300-301: Empty module segments return None
1195+
let temp_dir = TempDir::new().unwrap();
1196+
1197+
let original = std::env::var("CARGO_MANIFEST_DIR").ok();
1198+
unsafe { std::env::set_var("CARGO_MANIFEST_DIR", temp_dir.path()) };
1199+
1200+
// After filtering "crate", "Schema", segments is empty
1201+
let result = find_fk_column_from_target_entity("crate::Schema", "SomeRelation");
1202+
1203+
unsafe {
1204+
if let Some(dir) = original {
1205+
std::env::set_var("CARGO_MANIFEST_DIR", dir);
1206+
} else {
1207+
std::env::remove_var("CARGO_MANIFEST_DIR");
1208+
}
1209+
}
1210+
1211+
assert!(result.is_none(), "Empty module segments should return None");
1212+
}
1213+
1214+
#[test]
1215+
#[serial]
1216+
fn test_find_fk_column_from_target_entity_file_not_found() {
1217+
// Tests lines 307-309: File doesn't exist -> continue, then return None (line 333)
1218+
let temp_dir = TempDir::new().unwrap();
1219+
let src_dir = temp_dir.path().join("src");
1220+
std::fs::create_dir_all(&src_dir).unwrap();
1221+
1222+
let original = std::env::var("CARGO_MANIFEST_DIR").ok();
1223+
unsafe { std::env::set_var("CARGO_MANIFEST_DIR", temp_dir.path()) };
1224+
1225+
// Path to non-existent file
1226+
let result =
1227+
find_fk_column_from_target_entity("crate::models::nonexistent::Schema", "SomeRelation");
1228+
1229+
unsafe {
1230+
if let Some(dir) = original {
1231+
std::env::set_var("CARGO_MANIFEST_DIR", dir);
1232+
} else {
1233+
std::env::remove_var("CARGO_MANIFEST_DIR");
1234+
}
1235+
}
1236+
1237+
assert!(result.is_none(), "Non-existent file should return None");
1238+
}
1239+
1240+
#[test]
1241+
#[serial]
1242+
fn test_find_fk_column_from_target_entity_unparseable_file() {
1243+
// Tests line 312: File can't be parsed -> returns None
1244+
let temp_dir = TempDir::new().unwrap();
1245+
let src_dir = temp_dir.path().join("src");
1246+
let models_dir = src_dir.join("models");
1247+
std::fs::create_dir_all(&models_dir).unwrap();
1248+
1249+
// Create unparseable file
1250+
std::fs::write(models_dir.join("broken.rs"), "this is not valid rust {{{{").unwrap();
1251+
1252+
let original = std::env::var("CARGO_MANIFEST_DIR").ok();
1253+
unsafe { std::env::set_var("CARGO_MANIFEST_DIR", temp_dir.path()) };
1254+
1255+
let result =
1256+
find_fk_column_from_target_entity("crate::models::broken::Schema", "SomeRelation");
1257+
1258+
unsafe {
1259+
if let Some(dir) = original {
1260+
std::env::set_var("CARGO_MANIFEST_DIR", dir);
1261+
} else {
1262+
std::env::remove_var("CARGO_MANIFEST_DIR");
1263+
}
1264+
}
1265+
1266+
assert!(result.is_none(), "Unparseable file should return None");
1267+
}
1268+
1269+
#[test]
1270+
#[serial]
1271+
fn test_find_fk_column_from_target_entity_no_model_struct() {
1272+
// Tests lines 315-317: File exists but has no Model struct
1273+
let temp_dir = TempDir::new().unwrap();
1274+
let src_dir = temp_dir.path().join("src");
1275+
let models_dir = src_dir.join("models");
1276+
std::fs::create_dir_all(&models_dir).unwrap();
1277+
1278+
// Create file without Model struct
1279+
let content = r#"
1280+
pub struct SomethingElse {
1281+
pub id: i32,
1282+
}
1283+
pub enum Status { Active, Inactive }
1284+
"#;
1285+
std::fs::write(models_dir.join("nomodel.rs"), content).unwrap();
1286+
1287+
let original = std::env::var("CARGO_MANIFEST_DIR").ok();
1288+
unsafe { std::env::set_var("CARGO_MANIFEST_DIR", temp_dir.path()) };
1289+
1290+
let result =
1291+
find_fk_column_from_target_entity("crate::models::nomodel::Schema", "SomeRelation");
1292+
1293+
unsafe {
1294+
if let Some(dir) = original {
1295+
std::env::set_var("CARGO_MANIFEST_DIR", dir);
1296+
} else {
1297+
std::env::remove_var("CARGO_MANIFEST_DIR");
1298+
}
1299+
}
1300+
1301+
assert!(
1302+
result.is_none(),
1303+
"File without Model struct should return None"
1304+
);
1305+
}
1306+
1307+
#[test]
1308+
#[serial]
1309+
fn test_find_fk_column_from_target_entity_no_matching_relation_enum() {
1310+
// Tests lines 320-323: Model exists but no field matches the via_rel
1311+
let temp_dir = TempDir::new().unwrap();
1312+
let src_dir = temp_dir.path().join("src");
1313+
let models_dir = src_dir.join("models");
1314+
std::fs::create_dir_all(&models_dir).unwrap();
1315+
1316+
// Create model with different relation_enum
1317+
let model = r#"
1318+
pub struct Model {
1319+
pub id: i32,
1320+
pub user_id: i32,
1321+
#[sea_orm(belongs_to = "super::user::Entity", from = "user_id", to = "id", relation_enum = "Author")]
1322+
pub user: BelongsTo<super::user::Entity>,
1323+
}
1324+
"#;
1325+
std::fs::write(models_dir.join("comment.rs"), model).unwrap();
1326+
1327+
let original = std::env::var("CARGO_MANIFEST_DIR").ok();
1328+
unsafe { std::env::set_var("CARGO_MANIFEST_DIR", temp_dir.path()) };
1329+
1330+
// Search for "TargetUser" but only "Author" exists
1331+
let result =
1332+
find_fk_column_from_target_entity("crate::models::comment::Schema", "TargetUser");
1333+
1334+
unsafe {
1335+
if let Some(dir) = original {
1336+
std::env::set_var("CARGO_MANIFEST_DIR", dir);
1337+
} else {
1338+
std::env::remove_var("CARGO_MANIFEST_DIR");
1339+
}
1340+
}
1341+
1342+
assert!(
1343+
result.is_none(),
1344+
"Non-matching relation_enum should return None"
1345+
);
1346+
}
1347+
1348+
#[test]
1349+
#[serial]
1350+
fn test_find_fk_column_from_target_entity_tuple_struct() {
1351+
// Tests line 320: Model is a tuple struct (not named fields) -> skip
1352+
let temp_dir = TempDir::new().unwrap();
1353+
let src_dir = temp_dir.path().join("src");
1354+
let models_dir = src_dir.join("models");
1355+
std::fs::create_dir_all(&models_dir).unwrap();
1356+
1357+
// Create tuple struct Model
1358+
let model = "pub struct Model(i32, String);";
1359+
std::fs::write(models_dir.join("tuple.rs"), model).unwrap();
1360+
1361+
let original = std::env::var("CARGO_MANIFEST_DIR").ok();
1362+
unsafe { std::env::set_var("CARGO_MANIFEST_DIR", temp_dir.path()) };
1363+
1364+
let result =
1365+
find_fk_column_from_target_entity("crate::models::tuple::Schema", "SomeRelation");
1366+
1367+
unsafe {
1368+
if let Some(dir) = original {
1369+
std::env::set_var("CARGO_MANIFEST_DIR", dir);
1370+
} else {
1371+
std::env::remove_var("CARGO_MANIFEST_DIR");
1372+
}
1373+
}
1374+
1375+
assert!(result.is_none(), "Tuple struct Model should return None");
1376+
}
1377+
1378+
#[test]
1379+
#[serial]
1380+
fn test_find_fk_column_from_target_entity_field_no_from_attr() {
1381+
// Tests line 325: Field matches relation_enum but has no `from` attribute
1382+
let temp_dir = TempDir::new().unwrap();
1383+
let src_dir = temp_dir.path().join("src");
1384+
let models_dir = src_dir.join("models");
1385+
std::fs::create_dir_all(&models_dir).unwrap();
1386+
1387+
// Create model with relation_enum but no `from` attribute
1388+
let model = r#"
1389+
pub struct Model {
1390+
pub id: i32,
1391+
pub user_id: i32,
1392+
#[sea_orm(belongs_to = "super::user::Entity", to = "id", relation_enum = "TargetUser")]
1393+
pub user: BelongsTo<super::user::Entity>,
1394+
}
1395+
"#;
1396+
std::fs::write(models_dir.join("nofrom.rs"), model).unwrap();
1397+
1398+
let original = std::env::var("CARGO_MANIFEST_DIR").ok();
1399+
unsafe { std::env::set_var("CARGO_MANIFEST_DIR", temp_dir.path()) };
1400+
1401+
let result =
1402+
find_fk_column_from_target_entity("crate::models::nofrom::Schema", "TargetUser");
1403+
1404+
unsafe {
1405+
if let Some(dir) = original {
1406+
std::env::set_var("CARGO_MANIFEST_DIR", dir);
1407+
} else {
1408+
std::env::remove_var("CARGO_MANIFEST_DIR");
1409+
}
1410+
}
1411+
1412+
// extract_belongs_to_from_field returns None when no `from` attr
1413+
assert!(
1414+
result.is_none(),
1415+
"Field without 'from' attribute should return None"
1416+
);
1417+
}
11031418
}

0 commit comments

Comments
 (0)