Test whether dirs returned by glib are correct
[appimagekit/gsi.git] / tests / fixtures.h
blob0a779d58c60cb8848a3c857e9be0fb064dd325e7
1 #pragma once
3 #include <cerrno>
4 #include <ftw.h>
5 #include <unistd.h>
8 // fixture providing a temporary directory, and a temporary home directory within that directory
9 // overwrites HOME environment variable to ensure desktop files etc. are not installed in the system
10 class AppImageKitTest : public ::testing::Test {
11 private:
12 char* oldHome;
13 char* oldXdgDataHome;
14 char* oldXdgConfigHome;
16 public:
17 std::string tempDir;
18 std::string tempHome;
20 public:
21 AppImageKitTest() {
22 char* tmpl = strdup("/tmp/AppImageKit-unit-tests-XXXXXX");
23 tempDir = mkdtemp(tmpl);
24 delete[] tmpl;
26 tempHome = tempDir + "/HOME";
28 mkdir(tempHome.c_str(), 0700);
30 oldHome = getenv("HOME");
31 oldXdgDataHome = getenv("XDG_DATA_HOME");
32 oldXdgConfigHome = getenv("XDG_CONFIG_HOME");
34 std::string newXdgDataHome = tempHome + "/.local/share";
35 std::string newXdgConfigHome = tempHome + "/.config";
37 setenv("HOME", tempHome.c_str(), true);
38 setenv("XDG_DATA_HOME", newXdgDataHome.c_str(), true);
39 setenv("XDG_CONFIG_HOME", newXdgConfigHome.c_str(), true);
41 EXPECT_EQ(getenv("HOME"), tempHome);
42 EXPECT_EQ(tempHome, g_get_home_dir());
43 EXPECT_EQ(newXdgDataHome, g_get_user_data_dir());
44 EXPECT_EQ(newXdgConfigHome, g_get_user_config_dir());
47 ~AppImageKitTest() {
48 if (isDir(tempDir)) {
49 rmTree(tempDir);
52 if (oldHome != NULL) {
53 setenv("HOME", oldHome, true);
54 } else {
55 unsetenv("HOME");
58 if (oldXdgDataHome != NULL) {
59 setenv("XDG_DATA_HOME", oldXdgDataHome, true);
60 } else {
61 unsetenv("XDG_DATA_HOME");
64 if (oldXdgConfigHome != NULL) {
65 setenv("XDG_CONFIG_HOME", oldXdgConfigHome, true);
66 } else {
67 unsetenv("XDG_CONFIG_HOME");
71 private:
72 static const int rmTree(const std::string& path) {
73 int rv = nftw(path.c_str(), unlinkCb, 64, FTW_DEPTH|FTW_MOUNT|FTW_PHYS);
75 if (rv != 0) {
76 int error = errno;
77 std::cerr << "nftw() in rmTree(" << path << ") failed: " << strerror(error) << std::endl;
78 return rv;
81 return 0;
84 static int unlinkCb(const char* fpath, const struct stat* sb, int typeflag, struct FTW* ftwbuf) {
85 int rv;
87 switch (typeflag) {
88 case FTW_D:
89 case FTW_DNR:
90 case FTW_DP:
91 rv = rmdir(fpath);
92 break;
93 default:
94 rv = unlink(fpath);
95 break;
98 return rv;
101 public:
102 static const bool isFile(const std::string& path) {
103 struct stat st;
105 if (stat(path.c_str(), &st) != 0) {
106 perror("Failed to call stat(): ");
107 return false;
110 return S_ISREG(st.st_mode);
113 static const bool isDir(const std::string& path) {
114 struct stat st;
116 if (stat(path.c_str(), &st) != 0) {
117 perror("Failed to call stat(): ");
118 return false;
121 return S_ISDIR(st.st_mode);
124 static const std::vector<std::string> splitString(const std::string& s, char delim = ' ') {
125 std::vector<std::string> result;
127 std::stringstream ss(s);
128 std::string item;
130 while (std::getline(ss, item, delim)) {
131 result.push_back(item);
134 return result;
137 static const bool isEmptyString(const std::string& str) {
138 // check whether string is empty beforehand, as the string is interpreted as C string and contains a trailing \0
139 if (str.empty())
140 return true;
142 for (int i = 0; i < str.length(); i++) {
143 char chr = str[i];
144 if (chr != ' ' && chr != '\t')
145 return false;
148 return true;
151 static const bool stringStartsWith(const std::string& str, const std::string& prefix) {
152 for (int i = 0; i < prefix.length(); i++) {
153 if (str[i] != prefix[i])
154 return false;
157 return true;