A cross-platform Rust library for resolving XDG and platform-specific directories with proper fallbacks.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add extensive tests for new Dir methods with platform-specific behavior

Introduce modular, comprehensive test cases for `Dir` methods, covering
various platform-specific paths. New tests ensure accurate handling of
environmental variables, relative paths, platform defaults, and fallback
strategies:

- Add test suites for `bin_home`, `cache_home`, `config_home`,
`data_home`, `desktop`, `documents`, `downloads`, `fonts`, `home`,
`music`, `pictures`, `preferences`, `publicshare`, `runtime`,
`state_home`, and `templates`.
- Validate correct behavior for both Windows and Unix environments.
- Utilize `temp_env` for scoped environment variable handling.
- Ensure fallbacks to platform-specific directory standards when
variables are unset or paths are invalid.

Refactor existing tests to match the added modular structure.

+702 -167
+702 -167
src/lib.rs
··· 554 554 mod tests { 555 555 use super::*; 556 556 557 - #[test] 558 - fn test_resolve_xdg_path_absolute() { 559 - temp_env::with_var("TEST_XDG_VAR", Some("/absolute/path"), || { 560 - let result = Dir::resolve_xdg_path("TEST_XDG_VAR"); 561 - assert_eq!(result, Some(PathBuf::from("/absolute/path"))); 562 - }); 557 + mod bin_home { 558 + use temp_env::{with_var, with_var_unset}; 559 + 560 + use super::*; 561 + 562 + #[test] 563 + fn respects_xdg_bin_home() { 564 + let test_path = if cfg!(windows) { "C:\\test\\bin" } else { "/test/bin" }; 565 + with_var("XDG_BIN_HOME", Some(test_path), || { 566 + let result = Dir::bin_home(); 567 + assert_eq!(result, Some(PathBuf::from(test_path))); 568 + }); 569 + } 570 + 571 + #[test] 572 + fn ignores_relative_xdg_bin_home() { 573 + with_var("XDG_BIN_HOME", Some("relative/bin"), || { 574 + let result = Dir::bin_home(); 575 + 576 + if let Some(path) = result { 577 + assert!(path.is_absolute()); 578 + } 579 + }); 580 + } 581 + 582 + #[test] 583 + fn uses_platform_default_when_xdg_unset() { 584 + with_var_unset("XDG_BIN_HOME", || { 585 + let result = Dir::bin_home(); 586 + if let Some(bin_path) = result { 587 + assert!(bin_path.is_absolute()); 588 + 589 + #[cfg(any(target_os = "linux", target_os = "macos"))] 590 + assert!(bin_path.to_string_lossy().ends_with(".local/bin")); 591 + 592 + #[cfg(target_os = "windows")] 593 + assert!(bin_path.to_string_lossy().contains("Programs")); 594 + } 595 + }); 596 + } 563 597 } 564 598 565 - #[test] 566 - fn test_resolve_xdg_path_relative_ignored() { 567 - temp_env::with_var("TEST_XDG_VAR", Some("relative/path"), || { 568 - let result = Dir::resolve_xdg_path("TEST_XDG_VAR"); 569 - assert_eq!(result, None); 570 - }); 599 + mod cache_home { 600 + use temp_env::{with_var, with_var_unset}; 601 + 602 + use super::*; 603 + 604 + #[test] 605 + fn respects_xdg_cache_home() { 606 + let test_path = if cfg!(windows) { "C:\\test\\cache" } else { "/test/cache" }; 607 + with_var("XDG_CACHE_HOME", Some(test_path), || { 608 + let result = Dir::cache_home(); 609 + assert_eq!(result, Some(PathBuf::from(test_path))); 610 + }); 611 + } 612 + 613 + #[test] 614 + fn ignores_relative_xdg_cache_home() { 615 + with_var("XDG_CACHE_HOME", Some("relative/cache"), || { 616 + let result = Dir::cache_home(); 617 + if let Some(path) = result { 618 + assert!(path.is_absolute()); 619 + } 620 + }); 621 + } 622 + 623 + #[test] 624 + fn uses_platform_default_when_xdg_unset() { 625 + with_var_unset("XDG_CACHE_HOME", || { 626 + let result = Dir::cache_home(); 627 + if let Some(cache_path) = result { 628 + assert!(cache_path.is_absolute()); 629 + 630 + #[cfg(target_os = "linux")] 631 + assert!(cache_path.to_string_lossy().ends_with(".cache")); 632 + 633 + #[cfg(target_os = "macos")] 634 + assert!(cache_path.to_string_lossy().contains("Library/Caches")); 635 + 636 + #[cfg(target_os = "windows")] 637 + { 638 + if let Ok(localappdata) = env::var("LOCALAPPDATA") { 639 + assert_eq!(cache_path, PathBuf::from(localappdata)); 640 + } 641 + } 642 + } 643 + }); 644 + } 571 645 } 572 646 573 - #[test] 574 - fn test_resolve_xdg_path_unset() { 575 - temp_env::with_var_unset("TEST_XDG_VAR", || { 576 - let result = Dir::resolve_xdg_path("TEST_XDG_VAR"); 577 - assert_eq!(result, None); 578 - }); 647 + mod config_home { 648 + use temp_env::{with_var, with_var_unset}; 649 + 650 + use super::*; 651 + 652 + #[test] 653 + fn respects_xdg_config_home() { 654 + let test_path = if cfg!(windows) { "C:\\test\\config" } else { "/test/config" }; 655 + with_var("XDG_CONFIG_HOME", Some(test_path), || { 656 + let result = Dir::config_home(); 657 + assert_eq!(result, Some(PathBuf::from(test_path))); 658 + }); 659 + } 660 + 661 + #[test] 662 + fn ignores_relative_xdg_config_home() { 663 + with_var("XDG_CONFIG_HOME", Some("relative/config"), || { 664 + let result = Dir::config_home(); 665 + if let Some(path) = result { 666 + assert!(path.is_absolute()); 667 + } 668 + }); 669 + } 670 + 671 + #[test] 672 + fn uses_platform_default_when_xdg_unset() { 673 + with_var_unset("XDG_CONFIG_HOME", || { 674 + let result = Dir::config_home(); 675 + if let Some(config_path) = result { 676 + assert!(config_path.is_absolute()); 677 + 678 + #[cfg(target_os = "linux")] 679 + assert!(config_path.to_string_lossy().ends_with(".config")); 680 + 681 + #[cfg(target_os = "macos")] 682 + assert!(config_path.to_string_lossy().contains("Library/Application Support")); 683 + 684 + #[cfg(target_os = "windows")] 685 + { 686 + if let Ok(appdata) = env::var("APPDATA") { 687 + assert_eq!(config_path, PathBuf::from(appdata)); 688 + } 689 + } 690 + } 691 + }); 692 + } 579 693 } 580 694 581 - #[test] 582 - fn test_home_directory() { 583 - let home = Dir::home(); 584 - if let Some(home_path) = home { 585 - assert!(home_path.is_absolute()); 695 + mod config_local { 696 + use super::*; 697 + 698 + #[test] 699 + fn uses_localappdata_on_windows() { 700 + let result = Dir::config_local(); 701 + if let Some(config_local_path) = result { 702 + assert!(config_local_path.is_absolute()); 703 + 704 + #[cfg(target_os = "windows")] 705 + { 706 + if let Ok(localappdata) = env::var("LOCALAPPDATA") { 707 + assert_eq!(config_local_path, PathBuf::from(localappdata)); 708 + } 709 + } 710 + 711 + #[cfg(not(target_os = "windows"))] 712 + { 713 + assert_eq!(Some(config_local_path), Dir::config_home()); 714 + } 715 + } 716 + } 717 + 718 + #[test] 719 + fn matches_config_home_on_non_windows() { 720 + #[cfg(not(target_os = "windows"))] 721 + { 722 + let config_local = Dir::config_local(); 723 + let config_home = Dir::config_home(); 724 + assert_eq!(config_local, config_home); 725 + } 726 + } 727 + } 728 + 729 + mod data_home { 730 + use temp_env::{with_var, with_var_unset}; 731 + 732 + use super::*; 733 + 734 + #[test] 735 + fn respects_xdg_data_home() { 736 + let test_path = if cfg!(windows) { "C:\\test\\data" } else { "/test/data" }; 737 + with_var("XDG_DATA_HOME", Some(test_path), || { 738 + let result = Dir::data_home(); 739 + assert_eq!(result, Some(PathBuf::from(test_path))); 740 + }); 741 + } 742 + 743 + #[test] 744 + fn ignores_relative_xdg_data_home() { 745 + with_var("XDG_DATA_HOME", Some("relative/data"), || { 746 + let result = Dir::data_home(); 747 + if let Some(path) = result { 748 + assert!(path.is_absolute()); 749 + } 750 + }); 751 + } 752 + 753 + #[test] 754 + fn uses_platform_default_when_xdg_unset() { 755 + with_var_unset("XDG_DATA_HOME", || { 756 + let result = Dir::data_home(); 757 + if let Some(data_path) = result { 758 + assert!(data_path.is_absolute()); 759 + 760 + #[cfg(target_os = "linux")] 761 + assert!(data_path.to_string_lossy().ends_with(".local/share")); 762 + 763 + #[cfg(target_os = "macos")] 764 + assert!(data_path.to_string_lossy().contains("Library/Application Support")); 765 + 766 + #[cfg(target_os = "windows")] 767 + { 768 + if let Ok(appdata) = env::var("APPDATA") { 769 + assert_eq!(data_path, PathBuf::from(appdata)); 770 + } 771 + } 772 + } 773 + }); 586 774 } 587 775 } 588 776 589 - #[test] 590 - fn test_config_home_default() { 591 - temp_env::with_var_unset("XDG_CONFIG_HOME", || { 592 - let config = Dir::config_home(); 593 - if let Some(config_path) = config { 594 - assert!(config_path.is_absolute()); 777 + mod data_local { 778 + use super::*; 779 + 780 + #[test] 781 + fn uses_localappdata_on_windows() { 782 + let result = Dir::data_local(); 783 + if let Some(data_local_path) = result { 784 + assert!(data_local_path.is_absolute()); 785 + 786 + #[cfg(target_os = "windows")] 787 + { 788 + if let Ok(localappdata) = env::var("LOCALAPPDATA") { 789 + assert_eq!(data_local_path, PathBuf::from(localappdata)); 790 + } 791 + } 595 792 596 - #[cfg(target_os = "linux")] 597 - assert!(config_path.to_string_lossy().ends_with(".config")); 793 + #[cfg(not(target_os = "windows"))] 794 + { 795 + assert_eq!(Some(data_local_path), Dir::data_home()); 796 + } 797 + } 798 + } 598 799 599 - #[cfg(target_os = "macos")] 600 - assert!(config_path.to_string_lossy().contains("Library/Application Support")); 800 + #[test] 801 + fn matches_data_home_on_non_windows() { 802 + #[cfg(not(target_os = "windows"))] 803 + { 804 + let data_local = Dir::data_local(); 805 + let data_home = Dir::data_home(); 806 + assert_eq!(data_local, data_home); 601 807 } 602 - }); 808 + } 603 809 } 604 810 605 - #[test] 606 - fn test_config_home_xdg_override() { 607 - let test_path = if cfg!(windows) { "C:\\test\\config" } else { "/test/config" }; 608 - temp_env::with_var("XDG_CONFIG_HOME", Some(test_path), || { 609 - let config = Dir::config_home(); 610 - assert_eq!(config, Some(PathBuf::from(test_path))); 611 - }); 811 + mod desktop { 812 + use temp_env::{with_var, with_var_unset}; 813 + 814 + use super::*; 815 + 816 + #[test] 817 + fn respects_xdg_desktop_dir() { 818 + let test_path = if cfg!(windows) { "C:\\test\\desktop" } else { "/test/desktop" }; 819 + with_var("XDG_DESKTOP_DIR", Some(test_path), || { 820 + let result = Dir::desktop(); 821 + assert_eq!(result, Some(PathBuf::from(test_path))); 822 + }); 823 + } 824 + 825 + #[test] 826 + fn ignores_relative_xdg_desktop_dir() { 827 + with_var("XDG_DESKTOP_DIR", Some("relative/desktop"), || { 828 + let result = Dir::desktop(); 829 + if let Some(path) = result { 830 + assert!(path.is_absolute()); 831 + } 832 + }); 833 + } 834 + 835 + #[test] 836 + fn uses_platform_default_when_xdg_unset() { 837 + with_var_unset("XDG_DESKTOP_DIR", || { 838 + let result = Dir::desktop(); 839 + if let Some(desktop_path) = result { 840 + assert!(desktop_path.is_absolute()); 841 + assert!(desktop_path.to_string_lossy().ends_with("Desktop")); 842 + } 843 + }); 844 + } 612 845 } 613 846 614 - #[test] 615 - fn test_cache_home_default() { 616 - temp_env::with_var_unset("XDG_CACHE_HOME", || { 617 - let cache = Dir::cache_home(); 618 - if let Some(cache_path) = cache { 619 - assert!(cache_path.is_absolute()); 847 + mod documents { 848 + use temp_env::{with_var, with_var_unset}; 849 + 850 + use super::*; 851 + 852 + #[test] 853 + fn respects_xdg_documents_dir() { 854 + let test_path = if cfg!(windows) { "C:\\test\\documents" } else { "/test/documents" }; 855 + with_var("XDG_DOCUMENTS_DIR", Some(test_path), || { 856 + let result = Dir::documents(); 857 + assert_eq!(result, Some(PathBuf::from(test_path))); 858 + }); 859 + } 620 860 621 - #[cfg(target_os = "linux")] 622 - assert!(cache_path.to_string_lossy().ends_with(".cache")); 861 + #[test] 862 + fn ignores_relative_xdg_documents_dir() { 863 + with_var("XDG_DOCUMENTS_DIR", Some("relative/documents"), || { 864 + let result = Dir::documents(); 865 + if let Some(path) = result { 866 + assert!(path.is_absolute()); 867 + } 868 + }); 869 + } 623 870 624 - #[cfg(target_os = "macos")] 625 - assert!(cache_path.to_string_lossy().contains("Library/Caches")); 626 - } 627 - }); 871 + #[test] 872 + fn uses_platform_default_when_xdg_unset() { 873 + with_var_unset("XDG_DOCUMENTS_DIR", || { 874 + let result = Dir::documents(); 875 + if let Some(documents_path) = result { 876 + assert!(documents_path.is_absolute()); 877 + assert!(documents_path.to_string_lossy().ends_with("Documents")); 878 + } 879 + }); 880 + } 628 881 } 629 882 630 - #[test] 631 - fn test_data_home_default() { 632 - temp_env::with_var_unset("XDG_DATA_HOME", || { 633 - let data = Dir::data_home(); 634 - if let Some(data_path) = data { 635 - assert!(data_path.is_absolute()); 883 + mod downloads { 884 + use temp_env::{with_var, with_var_unset}; 636 885 637 - #[cfg(target_os = "linux")] 638 - assert!(data_path.to_string_lossy().ends_with(".local/share")); 886 + use super::*; 639 887 640 - #[cfg(target_os = "macos")] 641 - assert!(data_path.to_string_lossy().contains("Library/Application Support")); 642 - } 643 - }); 888 + #[test] 889 + fn respects_xdg_download_dir() { 890 + let test_path = if cfg!(windows) { "C:\\test\\downloads" } else { "/test/downloads" }; 891 + with_var("XDG_DOWNLOAD_DIR", Some(test_path), || { 892 + let result = Dir::downloads(); 893 + assert_eq!(result, Some(PathBuf::from(test_path))); 894 + }); 895 + } 896 + 897 + #[test] 898 + fn ignores_relative_xdg_download_dir() { 899 + with_var("XDG_DOWNLOAD_DIR", Some("relative/downloads"), || { 900 + let result = Dir::downloads(); 901 + if let Some(path) = result { 902 + assert!(path.is_absolute()); 903 + } 904 + }); 905 + } 906 + 907 + #[test] 908 + fn uses_platform_default_when_xdg_unset() { 909 + with_var_unset("XDG_DOWNLOAD_DIR", || { 910 + let result = Dir::downloads(); 911 + if let Some(downloads_path) = result { 912 + assert!(downloads_path.is_absolute()); 913 + assert!(downloads_path.to_string_lossy().ends_with("Downloads")); 914 + } 915 + }); 916 + } 644 917 } 645 918 646 - #[test] 647 - fn test_bin_home_default() { 648 - temp_env::with_var_unset("XDG_BIN_HOME", || { 649 - let bin = Dir::bin_home(); 650 - if let Some(bin_path) = bin { 651 - assert!(bin_path.is_absolute()); 919 + mod fonts { 920 + use super::*; 652 921 653 - #[cfg(any(target_os = "linux", target_os = "macos"))] 654 - assert!(bin_path.to_string_lossy().ends_with(".local/bin")); 922 + #[test] 923 + fn returns_platform_specific_path() { 924 + let result = Dir::fonts(); 925 + 926 + #[cfg(target_os = "linux")] 927 + if let Some(fonts_path) = result { 928 + assert!(fonts_path.is_absolute()); 929 + assert!(fonts_path.to_string_lossy().ends_with(".local/share/fonts")); 930 + } 655 931 656 - #[cfg(target_os = "windows")] 657 - assert!(bin_path.to_string_lossy().contains("Programs")); 932 + #[cfg(target_os = "macos")] 933 + if let Some(fonts_path) = result { 934 + assert!(fonts_path.is_absolute()); 935 + assert!(fonts_path.to_string_lossy().ends_with("Library/Fonts")); 658 936 } 659 - }); 660 - } 937 + 938 + #[cfg(target_os = "windows")] 939 + assert_eq!(result, None); 940 + } 661 941 662 - #[test] 663 - fn test_runtime_default() { 664 - temp_env::with_var_unset("XDG_RUNTIME_DIR", || { 665 - let runtime = Dir::runtime(); 666 - if let Some(runtime_path) = runtime { 667 - assert!(runtime_path.is_absolute()); 942 + #[test] 943 + fn returns_none_on_windows() { 944 + #[cfg(target_os = "windows")] 945 + { 946 + let result = Dir::fonts(); 947 + assert_eq!(result, None); 948 + } 949 + } 668 950 669 - #[cfg(any(target_os = "linux", target_os = "macos"))] 670 - { 671 - let path_str = runtime_path.to_string_lossy(); 672 - assert!(path_str.contains("tmp") || path_str.starts_with("/var/folders")); 951 + #[test] 952 + fn returns_some_on_unix() { 953 + #[cfg(any(target_os = "linux", target_os = "macos"))] 954 + { 955 + let result = Dir::fonts(); 956 + assert!(result.is_some()); 957 + if let Some(path) = result { 958 + assert!(path.is_absolute()); 673 959 } 674 960 } 675 - }); 961 + } 676 962 } 677 963 678 - #[test] 679 - fn test_desktop_default() { 680 - temp_env::with_var_unset("XDG_DESKTOP_DIR", || { 681 - let desktop = Dir::desktop(); 682 - if let Some(desktop_path) = desktop { 683 - assert!(desktop_path.is_absolute()); 684 - assert!(desktop_path.to_string_lossy().ends_with("Desktop")); 964 + mod home { 965 + use super::*; 966 + 967 + #[test] 968 + fn returns_absolute_path_when_available() { 969 + let result = Dir::home(); 970 + if let Some(home_path) = result { 971 + assert!(home_path.is_absolute()); 685 972 } 686 - }); 973 + } 974 + 975 + #[test] 976 + fn delegates_to_std_env_home_dir() { 977 + let std_result = std::env::home_dir(); 978 + let our_result = Dir::home(); 979 + assert_eq!(std_result, our_result); 980 + } 687 981 } 688 982 689 - #[test] 690 - fn test_videos_platform_differences() { 691 - temp_env::with_var_unset("XDG_VIDEOS_DIR", || { 692 - let videos = Dir::videos(); 693 - if let Some(videos_path) = videos { 694 - assert!(videos_path.is_absolute()); 983 + mod music { 984 + use temp_env::{with_var, with_var_unset}; 985 + 986 + use super::*; 695 987 696 - #[cfg(target_os = "linux")] 697 - assert!(videos_path.to_string_lossy().ends_with("Videos")); 988 + #[test] 989 + fn respects_xdg_music_dir() { 990 + let test_path = if cfg!(windows) { "C:\\test\\music" } else { "/test/music" }; 991 + with_var("XDG_MUSIC_DIR", Some(test_path), || { 992 + let result = Dir::music(); 993 + assert_eq!(result, Some(PathBuf::from(test_path))); 994 + }); 995 + } 698 996 699 - #[cfg(target_os = "macos")] 700 - assert!(videos_path.to_string_lossy().ends_with("Movies")); 997 + #[test] 998 + fn ignores_relative_xdg_music_dir() { 999 + with_var("XDG_MUSIC_DIR", Some("relative/music"), || { 1000 + let result = Dir::music(); 1001 + if let Some(path) = result { 1002 + assert!(path.is_absolute()); 1003 + } 1004 + }); 1005 + } 701 1006 702 - #[cfg(target_os = "windows")] 703 - assert!(videos_path.to_string_lossy().ends_with("Videos")); 704 - } 705 - }); 1007 + #[test] 1008 + fn uses_platform_default_when_xdg_unset() { 1009 + with_var_unset("XDG_MUSIC_DIR", || { 1010 + let result = Dir::music(); 1011 + if let Some(music_path) = result { 1012 + assert!(music_path.is_absolute()); 1013 + assert!(music_path.to_string_lossy().ends_with("Music")); 1014 + } 1015 + }); 1016 + } 706 1017 } 707 1018 708 - #[test] 709 - fn test_publicshare_windows_absolute() { 710 - temp_env::with_var_unset("XDG_PUBLICSHARE_DIR", || { 711 - let public = Dir::publicshare(); 712 - if let Some(public_path) = public { 713 - assert!(public_path.is_absolute()); 1019 + mod pictures { 1020 + use temp_env::{with_var, with_var_unset}; 1021 + 1022 + use super::*; 1023 + 1024 + #[test] 1025 + fn respects_xdg_pictures_dir() { 1026 + let test_path = if cfg!(windows) { "C:\\test\\pictures" } else { "/test/pictures" }; 1027 + with_var("XDG_PICTURES_DIR", Some(test_path), || { 1028 + let result = Dir::pictures(); 1029 + assert_eq!(result, Some(PathBuf::from(test_path))); 1030 + }); 1031 + } 714 1032 715 - #[cfg(target_os = "windows")] 716 - assert_eq!(public_path, PathBuf::from("C:\\Users\\Public")); 1033 + #[test] 1034 + fn ignores_relative_xdg_pictures_dir() { 1035 + with_var("XDG_PICTURES_DIR", Some("relative/pictures"), || { 1036 + let result = Dir::pictures(); 1037 + if let Some(path) = result { 1038 + assert!(path.is_absolute()); 1039 + } 1040 + }); 1041 + } 717 1042 718 - #[cfg(any(target_os = "linux", target_os = "macos"))] 719 - assert!(public_path.to_string_lossy().ends_with("Public")); 720 - } 721 - }); 1043 + #[test] 1044 + fn uses_platform_default_when_xdg_unset() { 1045 + with_var_unset("XDG_PICTURES_DIR", || { 1046 + let result = Dir::pictures(); 1047 + if let Some(pictures_path) = result { 1048 + assert!(pictures_path.is_absolute()); 1049 + assert!(pictures_path.to_string_lossy().ends_with("Pictures")); 1050 + } 1051 + }); 1052 + } 722 1053 } 723 1054 724 - #[test] 725 - fn test_config_local_default() { 726 - let config_local = Dir::config_local(); 727 - if let Some(config_local_path) = config_local { 728 - assert!(config_local_path.is_absolute()); 1055 + mod preferences { 1056 + use super::*; 1057 + 1058 + #[test] 1059 + fn returns_platform_specific_path() { 1060 + let result = Dir::preferences(); 1061 + if let Some(preferences_path) = result { 1062 + assert!(preferences_path.is_absolute()); 1063 + 1064 + #[cfg(target_os = "macos")] 1065 + assert!(preferences_path.to_string_lossy().ends_with("Library/Preferences")); 1066 + 1067 + #[cfg(not(target_os = "macos"))] 1068 + assert_eq!(Some(preferences_path), Dir::config_home()); 1069 + } 1070 + } 729 1071 730 - #[cfg(target_os = "windows")] 1072 + #[test] 1073 + fn matches_config_home_on_non_macos() { 1074 + #[cfg(not(target_os = "macos"))] 731 1075 { 732 - // On Windows, config_local should use LOCALAPPDATA 733 - let localappdata = env::var("LOCALAPPDATA").ok().map(PathBuf::from); 734 - assert_eq!(Some(config_local_path), localappdata); 1076 + let preferences = Dir::preferences(); 1077 + let config_home = Dir::config_home(); 1078 + assert_eq!(preferences, config_home); 735 1079 } 1080 + } 736 1081 737 - #[cfg(not(target_os = "windows"))] 1082 + #[test] 1083 + fn uses_library_preferences_on_macos() { 1084 + #[cfg(target_os = "macos")] 738 1085 { 739 - // On non-Windows, should be same as config_home 740 - assert_eq!(Some(config_local_path), Dir::config_home()); 1086 + let result = Dir::preferences(); 1087 + if let Some(path) = result { 1088 + assert!(path.to_string_lossy().ends_with("Library/Preferences")); 1089 + } 741 1090 } 742 1091 } 743 1092 } 744 1093 745 - #[test] 746 - fn test_data_local_default() { 747 - let data_local = Dir::data_local(); 748 - if let Some(data_local_path) = data_local { 749 - assert!(data_local_path.is_absolute()); 1094 + mod publicshare { 1095 + use temp_env::{with_var, with_var_unset}; 1096 + 1097 + use super::*; 1098 + 1099 + #[test] 1100 + fn respects_xdg_publicshare_dir() { 1101 + let test_path = if cfg!(windows) { "C:\\test\\public" } else { "/test/public" }; 1102 + with_var("XDG_PUBLICSHARE_DIR", Some(test_path), || { 1103 + let result = Dir::publicshare(); 1104 + assert_eq!(result, Some(PathBuf::from(test_path))); 1105 + }); 1106 + } 1107 + 1108 + #[test] 1109 + fn ignores_relative_xdg_publicshare_dir() { 1110 + with_var("XDG_PUBLICSHARE_DIR", Some("relative/public"), || { 1111 + let result = Dir::publicshare(); 1112 + if let Some(path) = result { 1113 + assert!(path.is_absolute()); 1114 + } 1115 + }); 1116 + } 1117 + 1118 + #[test] 1119 + fn uses_platform_default_when_xdg_unset() { 1120 + with_var_unset("XDG_PUBLICSHARE_DIR", || { 1121 + let result = Dir::publicshare(); 1122 + if let Some(public_path) = result { 1123 + assert!(public_path.is_absolute()); 750 1124 1125 + #[cfg(target_os = "windows")] 1126 + assert_eq!(public_path, PathBuf::from("C:\\Users\\Public")); 1127 + 1128 + #[cfg(any(target_os = "linux", target_os = "macos"))] 1129 + assert!(public_path.to_string_lossy().ends_with("Public")); 1130 + } 1131 + }); 1132 + } 1133 + 1134 + #[test] 1135 + fn uses_system_public_on_windows() { 751 1136 #[cfg(target_os = "windows")] 752 1137 { 753 - // On Windows, data_local should use LOCALAPPDATA 754 - let localappdata = env::var("LOCALAPPDATA").ok().map(PathBuf::from); 755 - assert_eq!(Some(data_local_path), localappdata); 1138 + with_var_unset("XDG_PUBLICSHARE_DIR", || { 1139 + let result = Dir::publicshare(); 1140 + assert_eq!(result, Some(PathBuf::from("C:\\Users\\Public"))); 1141 + }); 756 1142 } 1143 + } 1144 + } 757 1145 758 - #[cfg(not(target_os = "windows"))] 1146 + mod runtime { 1147 + use temp_env::{with_var, with_var_unset}; 1148 + 1149 + use super::*; 1150 + 1151 + #[test] 1152 + fn respects_xdg_runtime_dir() { 1153 + let test_path = if cfg!(windows) { "C:\\test\\runtime" } else { "/test/runtime" }; 1154 + with_var("XDG_RUNTIME_DIR", Some(test_path), || { 1155 + let result = Dir::runtime(); 1156 + assert_eq!(result, Some(PathBuf::from(test_path))); 1157 + }); 1158 + } 1159 + 1160 + #[test] 1161 + fn ignores_relative_xdg_runtime_dir() { 1162 + with_var("XDG_RUNTIME_DIR", Some("relative/runtime"), || { 1163 + let result = Dir::runtime(); 1164 + if let Some(path) = result { 1165 + assert!(path.is_absolute()); 1166 + } 1167 + }); 1168 + } 1169 + 1170 + #[test] 1171 + fn uses_platform_default_when_xdg_unset() { 1172 + with_var_unset("XDG_RUNTIME_DIR", || { 1173 + let result = Dir::runtime(); 1174 + if let Some(runtime_path) = result { 1175 + assert!(runtime_path.is_absolute()); 1176 + 1177 + #[cfg(any(target_os = "linux", target_os = "macos"))] 1178 + { 1179 + let path_str = runtime_path.to_string_lossy(); 1180 + assert!(path_str.contains("tmp") || path_str.starts_with("/var/folders")); 1181 + } 1182 + 1183 + #[cfg(target_os = "windows")] 1184 + { 1185 + if let Ok(temp) = env::var("TEMP") { 1186 + assert_eq!(runtime_path, PathBuf::from(temp)); 1187 + } 1188 + } 1189 + } 1190 + }); 1191 + } 1192 + 1193 + #[test] 1194 + fn falls_back_to_tmp_on_unix() { 1195 + #[cfg(any(target_os = "linux", target_os = "macos"))] 759 1196 { 760 - // On non-Windows, should be same as data_home 761 - assert_eq!(Some(data_local_path), Dir::data_home()); 1197 + with_var_unset("XDG_RUNTIME_DIR", || { 1198 + with_var_unset("TMPDIR", || { 1199 + let result = Dir::runtime(); 1200 + assert_eq!(result, Some(PathBuf::from("/tmp"))); 1201 + }); 1202 + }); 762 1203 } 763 1204 } 764 1205 } 765 1206 766 - #[test] 767 - fn test_fonts_platform_differences() { 768 - let fonts = Dir::fonts(); 1207 + mod state_home { 1208 + use temp_env::{with_var, with_var_unset}; 1209 + 1210 + use super::*; 1211 + 1212 + #[test] 1213 + fn respects_xdg_state_home() { 1214 + let test_path = if cfg!(windows) { "C:\\test\\state" } else { "/test/state" }; 1215 + with_var("XDG_STATE_HOME", Some(test_path), || { 1216 + let result = Dir::state_home(); 1217 + assert_eq!(result, Some(PathBuf::from(test_path))); 1218 + }); 1219 + } 1220 + 1221 + #[test] 1222 + fn ignores_relative_xdg_state_home() { 1223 + with_var("XDG_STATE_HOME", Some("relative/state"), || { 1224 + let result = Dir::state_home(); 1225 + if let Some(path) = result { 1226 + assert!(path.is_absolute()); 1227 + } 1228 + }); 1229 + } 1230 + 1231 + #[test] 1232 + fn uses_platform_default_when_xdg_unset() { 1233 + with_var_unset("XDG_STATE_HOME", || { 1234 + let result = Dir::state_home(); 1235 + if let Some(state_path) = result { 1236 + assert!(state_path.is_absolute()); 1237 + 1238 + #[cfg(target_os = "linux")] 1239 + assert!(state_path.to_string_lossy().ends_with(".local/state")); 769 1240 770 - #[cfg(target_os = "linux")] 771 - if let Some(fonts_path) = fonts { 772 - assert!(fonts_path.is_absolute()); 773 - assert!(fonts_path.to_string_lossy().ends_with(".local/share/fonts")); 1241 + #[cfg(target_os = "macos")] 1242 + assert!(state_path.to_string_lossy().contains("Library/Application Support")); 1243 + 1244 + #[cfg(target_os = "windows")] 1245 + { 1246 + if let Ok(localappdata) = env::var("LOCALAPPDATA") { 1247 + assert_eq!(state_path, PathBuf::from(localappdata)); 1248 + } 1249 + } 1250 + } 1251 + }); 774 1252 } 1253 + } 775 1254 776 - #[cfg(target_os = "macos")] 777 - if let Some(fonts_path) = fonts { 778 - assert!(fonts_path.is_absolute()); 779 - assert!(fonts_path.to_string_lossy().ends_with("Library/Fonts")); 1255 + mod templates { 1256 + use temp_env::{with_var, with_var_unset}; 1257 + 1258 + use super::*; 1259 + 1260 + #[test] 1261 + fn respects_xdg_templates_dir() { 1262 + let test_path = if cfg!(windows) { "C:\\test\\templates" } else { "/test/templates" }; 1263 + with_var("XDG_TEMPLATES_DIR", Some(test_path), || { 1264 + let result = Dir::templates(); 1265 + assert_eq!(result, Some(PathBuf::from(test_path))); 1266 + }); 780 1267 } 781 1268 782 - #[cfg(target_os = "windows")] 783 - assert_eq!(fonts, None); 1269 + #[test] 1270 + fn ignores_relative_xdg_templates_dir() { 1271 + with_var("XDG_TEMPLATES_DIR", Some("relative/templates"), || { 1272 + let result = Dir::templates(); 1273 + if let Some(path) = result { 1274 + assert!(path.is_absolute()); 1275 + } 1276 + }); 1277 + } 1278 + 1279 + #[test] 1280 + fn uses_platform_default_when_xdg_unset() { 1281 + with_var_unset("XDG_TEMPLATES_DIR", || { 1282 + let result = Dir::templates(); 1283 + if let Some(templates_path) = result { 1284 + assert!(templates_path.is_absolute()); 1285 + assert!(templates_path.to_string_lossy().ends_with("Templates")); 1286 + } 1287 + }); 1288 + } 784 1289 } 785 1290 786 - #[test] 787 - fn test_preferences_platform_differences() { 788 - let preferences = Dir::preferences(); 789 - if let Some(preferences_path) = preferences { 790 - assert!(preferences_path.is_absolute()); 1291 + mod videos { 1292 + use temp_env::{with_var, with_var_unset}; 1293 + 1294 + use super::*; 791 1295 792 - #[cfg(target_os = "macos")] 793 - assert!(preferences_path.to_string_lossy().ends_with("Library/Preferences")); 1296 + #[test] 1297 + fn respects_xdg_videos_dir() { 1298 + let test_path = if cfg!(windows) { "C:\\test\\videos" } else { "/test/videos" }; 1299 + with_var("XDG_VIDEOS_DIR", Some(test_path), || { 1300 + let result = Dir::videos(); 1301 + assert_eq!(result, Some(PathBuf::from(test_path))); 1302 + }); 1303 + } 794 1304 795 - #[cfg(not(target_os = "macos"))] 796 - assert_eq!(Some(preferences_path), Dir::config_home()); 1305 + #[test] 1306 + fn ignores_relative_xdg_videos_dir() { 1307 + with_var("XDG_VIDEOS_DIR", Some("relative/videos"), || { 1308 + let result = Dir::videos(); 1309 + if let Some(path) = result { 1310 + assert!(path.is_absolute()); 1311 + } 1312 + }); 1313 + } 1314 + 1315 + #[test] 1316 + fn uses_platform_default_when_xdg_unset() { 1317 + with_var_unset("XDG_VIDEOS_DIR", || { 1318 + let result = Dir::videos(); 1319 + if let Some(videos_path) = result { 1320 + assert!(videos_path.is_absolute()); 1321 + 1322 + #[cfg(target_os = "linux")] 1323 + assert!(videos_path.to_string_lossy().ends_with("Videos")); 1324 + 1325 + #[cfg(target_os = "macos")] 1326 + assert!(videos_path.to_string_lossy().ends_with("Movies")); 1327 + 1328 + #[cfg(target_os = "windows")] 1329 + assert!(videos_path.to_string_lossy().ends_with("Videos")); 1330 + } 1331 + }); 797 1332 } 798 1333 } 799 1334 }