1 use std::env;
2 use std::io;
3 use std::path;
4 use std::sync;
5 
6 use app_dirs2::AppDataType;
7 use test_case::test_case;
8 
9 // This test suite checks the effects of the app_dirs2 crate on the file system.
10 //
11 // The functions with the prefix get_ should not touch the file system.  The functions without the
12 // prefix should create the returned directory if it doesn’t exist.
13 //
14 // As only the unix/XDG implementation supports changing the root configuration directory, we can
15 // only run this test suite on this platform.  As we use environment variables to set the
16 // configuration root, we have to make sure that the tests are run in sequence and don’t overlap,
17 // see the `ENV_MUTEX` mutex.
18 
19 lazy_static::lazy_static! {
20     // For test cases that depend on environment variables
21     static ref ENV_MUTEX: sync::Mutex<()> = sync::Mutex::new(());
22 }
23 
set_root_dir(path: &path::Path) -> path::PathBuf24 fn set_root_dir(path: &path::Path) -> path::PathBuf {
25     let root = path.join("root");
26     env::set_var("HOME", &root.join("home"));
27     env::set_var("XDG_CACHE_HOME", "");
28     env::set_var("XDG_CONFIG_HOME", "");
29     env::set_var("XDG_DATA_HOME", "");
30     env::set_var("XDG_DATA_DIRS", &root.join("data"));
31     env::set_var("XDG_CONFIG_DIRS", &root.join("config"));
32     root
33 }
34 
35 #[test_case(AppDataType::UserCache; "user cache")]
36 #[test_case(AppDataType::UserConfig; "user config")]
37 #[test_case(AppDataType::UserData; "user data")]
38 #[test_case(AppDataType::SharedConfig; "shared config")]
39 #[test_case(AppDataType::SharedData; "shared data")]
40 #[cfg(all(unix, not(target_os = "macos"), not(target_os = "android")))]
test_no_create(ty: AppDataType) -> io::Result<()>41 fn test_no_create(ty: AppDataType) -> io::Result<()> {
42     let _env_guard = ENV_MUTEX.lock();
43 
44     let dir = tempfile::tempdir()?;
45     let root_dir = set_root_dir(dir.path());
46 
47     let info = app_dirs2::AppInfo {
48         name: "test-app".into(),
49         author: "test-author".into(),
50     };
51 
52     let data_root = app_dirs2::get_data_root(ty).unwrap();
53     assert!(
54         data_root.starts_with(&root_dir),
55         "Data root does not start with root dir: data root = {}, root dir = {}",
56         data_root.display(),
57         root_dir.display()
58     );
59     assert!(!root_dir.exists());
60 
61     let app_root = app_dirs2::get_app_root(ty, &info).unwrap();
62     assert!(
63         app_root.starts_with(&data_root),
64         "App root does not start with data root: app root = {}, data root = {}",
65         app_root.display(),
66         data_root.display()
67     );
68     assert!(!root_dir.exists());
69 
70     let app_dir = app_dirs2::get_app_dir(ty, &info, "testdir").unwrap();
71     assert!(
72         app_dir.starts_with(&app_root),
73         "App dir does not start with app root: app dir = {}, app root = {}",
74         app_dir.display(),
75         app_root.display()
76     );
77     assert!(!root_dir.exists());
78 
79     dir.close()
80 }
81 
82 #[test_case(AppDataType::UserCache; "user cache")]
83 #[test_case(AppDataType::UserConfig; "user config")]
84 #[test_case(AppDataType::UserData; "user data")]
85 #[test_case(AppDataType::SharedConfig; "shared config")]
86 #[test_case(AppDataType::SharedData; "shared data")]
87 #[cfg(all(unix, not(target_os = "macos"), not(target_os = "android")))]
test_create(ty: AppDataType) -> io::Result<()>88 fn test_create(ty: AppDataType) -> io::Result<()> {
89     let _env_guard = ENV_MUTEX.lock();
90 
91     let dir = tempfile::tempdir()?;
92     let root_dir = set_root_dir(dir.path());
93 
94     let info = app_dirs2::AppInfo {
95         name: "test-app".into(),
96         author: "test-author".into(),
97     };
98 
99     let data_root = app_dirs2::data_root(ty).unwrap();
100     assert!(
101         data_root.starts_with(&root_dir),
102         "Data root does not start with root dir: data root = {}, root dir = {}",
103         data_root.display(),
104         root_dir.display()
105     );
106     assert!(data_root.is_dir());
107 
108     let app_root = app_dirs2::app_root(ty, &info).unwrap();
109     assert!(
110         app_root.starts_with(&data_root),
111         "App root does not start with data root: app root = {}, data root = {}",
112         app_root.display(),
113         data_root.display()
114     );
115     assert!(app_root.is_dir());
116 
117     let app_dir = app_dirs2::app_dir(ty, &info, "testdir").unwrap();
118     assert!(
119         app_dir.starts_with(&app_root),
120         "App dir does not start with app root: app dir = {}, app root = {}",
121         app_dir.display(),
122         app_root.display()
123     );
124     assert!(app_dir.is_dir());
125 
126     dir.close()
127 }
128