@@ -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