Skip to content

Commit 81fad19

Browse files
committed
Add testcase
1 parent c1d2f26 commit 81fad19

1 file changed

Lines changed: 217 additions & 0 deletions

File tree

crates/vespera_macro/src/schema_macro/inline_types.rs

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,4 +791,221 @@ mod tests {
791791
// Should use the override name, not the struct name
792792
assert_eq!(inline_type.type_name.to_string(), "UserSchema_Memos");
793793
}
794+
795+
// Tests for public functions with file lookup (lines 43, 45, 114, 116-118, 120)
796+
// These require setting up a temp directory with model files
797+
798+
#[test]
799+
fn test_generate_inline_relation_type_with_file_lookup() {
800+
use tempfile::TempDir;
801+
802+
// Create temp directory structure
803+
let temp_dir = TempDir::new().unwrap();
804+
let src_dir = temp_dir.path().join("src");
805+
let models_dir = src_dir.join("models");
806+
std::fs::create_dir_all(&models_dir).unwrap();
807+
808+
// Create a user.rs file with Model struct that has circular reference
809+
let user_model = r#"
810+
pub struct Model {
811+
pub id: i32,
812+
pub name: String,
813+
pub memo: BelongsTo<memo::Entity>,
814+
}
815+
"#;
816+
std::fs::write(models_dir.join("user.rs"), user_model).unwrap();
817+
818+
// Save original CARGO_MANIFEST_DIR and set to temp dir
819+
let original_manifest_dir = std::env::var("CARGO_MANIFEST_DIR").ok();
820+
// SAFETY: This is a test that runs single-threaded
821+
unsafe { std::env::set_var("CARGO_MANIFEST_DIR", temp_dir.path()) };
822+
823+
// Test generate_inline_relation_type (lines 43, 45)
824+
let parent_type_name = syn::Ident::new("MemoSchema", proc_macro2::Span::call_site());
825+
let rel_info = RelationFieldInfo {
826+
field_name: syn::Ident::new("user", proc_macro2::Span::call_site()),
827+
relation_type: "BelongsTo".to_string(),
828+
schema_path: quote!(crate::models::user::Schema),
829+
is_optional: false,
830+
inline_type_info: None,
831+
};
832+
let source_module_path = vec![
833+
"crate".to_string(),
834+
"models".to_string(),
835+
"memo".to_string(),
836+
];
837+
838+
let result =
839+
generate_inline_relation_type(&parent_type_name, &rel_info, &source_module_path, None);
840+
841+
// Restore original CARGO_MANIFEST_DIR
842+
// SAFETY: This is a test that runs single-threaded
843+
unsafe {
844+
if let Some(dir) = original_manifest_dir {
845+
std::env::set_var("CARGO_MANIFEST_DIR", dir);
846+
} else {
847+
std::env::remove_var("CARGO_MANIFEST_DIR");
848+
}
849+
}
850+
851+
// Verify result
852+
assert!(result.is_some());
853+
let inline_type = result.unwrap();
854+
assert_eq!(inline_type.type_name.to_string(), "MemoSchema_User");
855+
856+
// Should have id and name, but not memo (circular)
857+
let field_names: Vec<String> = inline_type
858+
.fields
859+
.iter()
860+
.map(|f| f.name.to_string())
861+
.collect();
862+
assert!(field_names.contains(&"id".to_string()));
863+
assert!(field_names.contains(&"name".to_string()));
864+
assert!(!field_names.contains(&"memo".to_string()));
865+
}
866+
867+
#[test]
868+
fn test_generate_inline_relation_type_no_relations_with_file_lookup() {
869+
use tempfile::TempDir;
870+
871+
// Create temp directory structure
872+
let temp_dir = TempDir::new().unwrap();
873+
let src_dir = temp_dir.path().join("src");
874+
let models_dir = src_dir.join("models");
875+
std::fs::create_dir_all(&models_dir).unwrap();
876+
877+
// Create a memo.rs file with Model struct that has relations
878+
let memo_model = r#"
879+
pub struct Model {
880+
pub id: i32,
881+
pub title: String,
882+
pub user: BelongsTo<user::Entity>,
883+
pub comments: HasMany<comment::Entity>,
884+
}
885+
"#;
886+
std::fs::write(models_dir.join("memo.rs"), memo_model).unwrap();
887+
888+
// Save original CARGO_MANIFEST_DIR and set to temp dir
889+
let original_manifest_dir = std::env::var("CARGO_MANIFEST_DIR").ok();
890+
// SAFETY: This is a test that runs single-threaded
891+
unsafe { std::env::set_var("CARGO_MANIFEST_DIR", temp_dir.path()) };
892+
893+
// Test generate_inline_relation_type_no_relations (lines 114, 116-118, 120)
894+
let parent_type_name = syn::Ident::new("UserSchema", proc_macro2::Span::call_site());
895+
let rel_info = RelationFieldInfo {
896+
field_name: syn::Ident::new("memos", proc_macro2::Span::call_site()),
897+
relation_type: "HasMany".to_string(),
898+
schema_path: quote!(crate::models::memo::Schema),
899+
is_optional: false,
900+
inline_type_info: None,
901+
};
902+
903+
let result = generate_inline_relation_type_no_relations(&parent_type_name, &rel_info, None);
904+
905+
// Restore original CARGO_MANIFEST_DIR
906+
// SAFETY: This is a test that runs single-threaded
907+
unsafe {
908+
if let Some(dir) = original_manifest_dir {
909+
std::env::set_var("CARGO_MANIFEST_DIR", dir);
910+
} else {
911+
std::env::remove_var("CARGO_MANIFEST_DIR");
912+
}
913+
}
914+
915+
// Verify result
916+
assert!(result.is_some());
917+
let inline_type = result.unwrap();
918+
assert_eq!(inline_type.type_name.to_string(), "UserSchema_Memos");
919+
920+
// Should have id and title, but not user or comments (relations)
921+
let field_names: Vec<String> = inline_type
922+
.fields
923+
.iter()
924+
.map(|f| f.name.to_string())
925+
.collect();
926+
assert!(field_names.contains(&"id".to_string()));
927+
assert!(field_names.contains(&"title".to_string()));
928+
assert!(!field_names.contains(&"user".to_string()));
929+
assert!(!field_names.contains(&"comments".to_string()));
930+
}
931+
932+
#[test]
933+
fn test_generate_inline_relation_type_file_not_found() {
934+
use tempfile::TempDir;
935+
936+
// Create temp directory structure without the model file
937+
let temp_dir = TempDir::new().unwrap();
938+
let src_dir = temp_dir.path().join("src");
939+
std::fs::create_dir_all(&src_dir).unwrap();
940+
941+
// Save original CARGO_MANIFEST_DIR and set to temp dir
942+
let original_manifest_dir = std::env::var("CARGO_MANIFEST_DIR").ok();
943+
// SAFETY: This is a test that runs single-threaded
944+
unsafe { std::env::set_var("CARGO_MANIFEST_DIR", temp_dir.path()) };
945+
946+
let parent_type_name = syn::Ident::new("TestSchema", proc_macro2::Span::call_site());
947+
let rel_info = RelationFieldInfo {
948+
field_name: syn::Ident::new("user", proc_macro2::Span::call_site()),
949+
relation_type: "BelongsTo".to_string(),
950+
schema_path: quote!(crate::models::nonexistent::Schema),
951+
is_optional: false,
952+
inline_type_info: None,
953+
};
954+
let source_module_path = vec!["crate".to_string()];
955+
956+
let result =
957+
generate_inline_relation_type(&parent_type_name, &rel_info, &source_module_path, None);
958+
959+
// Restore original CARGO_MANIFEST_DIR
960+
// SAFETY: This is a test that runs single-threaded
961+
unsafe {
962+
if let Some(dir) = original_manifest_dir {
963+
std::env::set_var("CARGO_MANIFEST_DIR", dir);
964+
} else {
965+
std::env::remove_var("CARGO_MANIFEST_DIR");
966+
}
967+
}
968+
969+
// Should return None when file not found
970+
assert!(result.is_none());
971+
}
972+
973+
#[test]
974+
fn test_generate_inline_relation_type_no_relations_file_not_found() {
975+
use tempfile::TempDir;
976+
977+
// Create temp directory structure without the model file
978+
let temp_dir = TempDir::new().unwrap();
979+
let src_dir = temp_dir.path().join("src");
980+
std::fs::create_dir_all(&src_dir).unwrap();
981+
982+
// Save original CARGO_MANIFEST_DIR and set to temp dir
983+
let original_manifest_dir = std::env::var("CARGO_MANIFEST_DIR").ok();
984+
// SAFETY: This is a test that runs single-threaded
985+
unsafe { std::env::set_var("CARGO_MANIFEST_DIR", temp_dir.path()) };
986+
987+
let parent_type_name = syn::Ident::new("TestSchema", proc_macro2::Span::call_site());
988+
let rel_info = RelationFieldInfo {
989+
field_name: syn::Ident::new("items", proc_macro2::Span::call_site()),
990+
relation_type: "HasMany".to_string(),
991+
schema_path: quote!(crate::models::nonexistent::Schema),
992+
is_optional: false,
993+
inline_type_info: None,
994+
};
995+
996+
let result = generate_inline_relation_type_no_relations(&parent_type_name, &rel_info, None);
997+
998+
// Restore original CARGO_MANIFEST_DIR
999+
// SAFETY: This is a test that runs single-threaded
1000+
unsafe {
1001+
if let Some(dir) = original_manifest_dir {
1002+
std::env::set_var("CARGO_MANIFEST_DIR", dir);
1003+
} else {
1004+
std::env::remove_var("CARGO_MANIFEST_DIR");
1005+
}
1006+
}
1007+
1008+
// Should return None when file not found
1009+
assert!(result.is_none());
1010+
}
7941011
}

0 commit comments

Comments
 (0)