Fix Content-Transfer-Encoding value
[TortoiseGit.git] / test / UnitTests / libgitTest.cpp
blob192d3e0a49609f56a77564d8083eea899f226f5b
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2016-2018 - TortoiseGit
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "stdafx.h"
21 #include "Git.h"
22 #include "StringUtils.h"
23 #include "gitdll.h"
25 TEST(libgit, BrokenConfig)
27 CAutoTempDir tempdir;
28 g_Git.m_CurrentDir = tempdir.GetTempDir();
29 g_Git.m_IsGitDllInited = false;
30 g_Git.m_CurrentDir = g_Git.m_CurrentDir;
31 g_Git.m_IsUseGitDLL = true;
32 g_Git.m_IsUseLibGit2 = false;
33 g_Git.m_IsUseLibGit2_mask = 0;
34 // libgit relies on CWD being set to working tree
35 SetCurrentDirectory(g_Git.m_CurrentDir);
37 CString output;
38 EXPECT_EQ(0, g_Git.Run(L"git.exe init", &output, CP_UTF8));
39 EXPECT_STRNE(L"", output);
40 CString testFile = tempdir.GetTempDir() + L"\\.git\\config";
41 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(testFile, L"[push]\ndefault=something-that-is-invalid\n"));
43 EXPECT_THROW(g_Git.CheckAndInitDll(), const char*);
46 TEST(libgit, Mailmap)
48 CAutoTempDir tempdir;
49 g_Git.m_CurrentDir = tempdir.GetTempDir();
50 // libgit relies on CWD being set to working tree
51 SetCurrentDirectory(g_Git.m_CurrentDir);
53 GIT_MAILMAP mailmap = (void*)0x12345678;
54 git_read_mailmap(&mailmap);
55 EXPECT_EQ(nullptr, mailmap);
57 CString mailmapFile = tempdir.GetTempDir() + L"\\.mailmap";
58 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(mailmapFile, L""));
60 mailmap = (void*)0x12345678;
61 git_read_mailmap(&mailmap);
62 EXPECT_EQ(nullptr, mailmap);
64 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(mailmapFile, L"Sven Strickroth <sven@tortoisegit.org>"));
65 git_read_mailmap(&mailmap);
66 EXPECT_NE(nullptr, mailmap);
67 const char* email1 = nullptr;
68 const char* author1 = nullptr;
69 EXPECT_EQ(-1, git_lookup_mailmap(mailmap, &email1, &author1, "email@cs-ware.de", nullptr, [](void*) { return "Sven S."; }));
70 EXPECT_EQ(0, git_lookup_mailmap(mailmap, &email1, &author1, "sven@tortoisegit.org", nullptr, [](void*) { return "Sven S."; }));
71 EXPECT_EQ(nullptr, email1);
72 EXPECT_STREQ("Sven Strickroth", author1);
74 email1 = nullptr;
75 author1 = nullptr;
76 EXPECT_EQ(0, git_lookup_mailmap(mailmap, &email1, &author1, "Sven@tortoisegit.org", nullptr, [](void*) { return "Sven S."; }));
77 EXPECT_EQ(nullptr, email1);
78 EXPECT_STREQ("Sven Strickroth", author1);
80 git_free_mailmap(mailmap);
81 CString content;
82 for (auto& entry : { L"", L"1", L"2", L"A", L"4", L"5", L"b", L"7" })
83 content.AppendFormat(L"Sven%s Strickroth <sven%s@tortoisegit.org> <email%s@cs-ware.de>\n", entry, entry, entry);
84 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(mailmapFile, content));
85 git_read_mailmap(&mailmap);
86 EXPECT_NE(nullptr, mailmap);
87 email1 = nullptr;
88 author1 = nullptr;
89 EXPECT_EQ(-1, git_lookup_mailmap(mailmap, &email1, &author1, "sven@tortoisegit.org", nullptr, [](void*) { return "Sven S."; }));
90 EXPECT_EQ(-1, git_lookup_mailmap(mailmap, &email1, &author1, "aaa@tortoisegit.org", nullptr, [](void*) { return "Sven S."; }));
91 EXPECT_EQ(-1, git_lookup_mailmap(mailmap, &email1, &author1, "zzz@tortoisegit.org", nullptr, [](void*) { return "Sven S."; }));
92 for (auto& entry : { "", "1", "2", "A", "4", "5", "b", "7" })
94 CStringA maillookup, mail, name;
95 maillookup.Format("email%s@cs-ware.de", entry);
96 mail.Format("sven%s@tortoisegit.org", entry);
97 name.Format("Sven%s Strickroth", entry);
98 email1 = nullptr;
99 author1 = nullptr;
100 EXPECT_EQ(0, git_lookup_mailmap(mailmap, &email1, &author1, maillookup, nullptr, [](void*) { return "Sven S."; }));
101 EXPECT_STREQ(mail, email1);
102 EXPECT_STREQ(name, author1);
105 email1 = nullptr;
106 author1 = nullptr;
107 EXPECT_EQ(0, git_lookup_mailmap(mailmap, &email1, &author1, "email@cs-ware.de", nullptr, [](void*) { return "Sven Strickroth"; }));
108 EXPECT_STREQ("sven@tortoisegit.org", email1);
109 EXPECT_STREQ("Sven Strickroth", author1);
111 git_free_mailmap(mailmap);
112 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(mailmapFile, L"<sven@tortoisegit.org> <email@cs-ware.de>\nSven S. <sven@tortoisegit.org> Sven Strickroth <email@cs-ware.de>"));
113 git_read_mailmap(&mailmap);
114 EXPECT_NE(nullptr, mailmap);
115 email1 = nullptr;
116 author1 = nullptr;
117 EXPECT_EQ(-1, git_lookup_mailmap(mailmap, &email1, &author1, "sven@tortoisegit.org", nullptr, [](void*) { return "Sven S."; }));
118 EXPECT_EQ(-1, git_lookup_mailmap(mailmap, &email1, &author1, "aaa@tortoisegit.org", nullptr, [](void*) { return "Sven S."; }));
119 EXPECT_EQ(-1, git_lookup_mailmap(mailmap, &email1, &author1, "zzz@tortoisegit.org", nullptr, [](void*) { return "Sven S."; }));
120 EXPECT_EQ(0, git_lookup_mailmap(mailmap, &email1, &author1, "email@cs-ware.de", nullptr, [](void*) { return "Sven S."; }));
121 EXPECT_STREQ("sven@tortoisegit.org", email1);
122 EXPECT_STREQ(nullptr, author1);
123 email1 = nullptr;
124 author1 = nullptr;
125 EXPECT_EQ(0, git_lookup_mailmap(mailmap, &email1, &author1, "email@cs-ware.de", nullptr, [](void*) { return "Sven Strickroth"; }));
126 EXPECT_STREQ("sven@tortoisegit.org", email1);
127 EXPECT_STREQ("Sven S.", author1);
130 TEST(libgit, MkDir)
132 CAutoTempDir tempdir;
133 CString subdir = tempdir.GetTempDir() + L"\\abc";
135 EXPECT_FALSE(PathFileExists(subdir));
136 EXPECT_EQ(0, git_mkdir(CUnicodeUtils::GetUTF8(subdir)));
137 EXPECT_TRUE(PathFileExists(subdir));
138 EXPECT_TRUE(PathIsDirectory(subdir));
139 EXPECT_EQ(-1, git_mkdir(CUnicodeUtils::GetUTF8(subdir)));
142 TEST(libgit, RefreshIndex)
144 CAutoTempDir tempdir;
145 g_Git.m_CurrentDir = tempdir.GetTempDir();
146 g_Git.m_bInitialized = false;
147 g_Git.m_IsGitDllInited = false;
148 g_Git.m_IsUseGitDLL = true;
149 g_Git.m_IsUseLibGit2 = false;
150 g_Git.m_IsUseLibGit2_mask = 0;
152 // libgit relies on CWD being set to working tree
153 SetCurrentDirectory(g_Git.m_CurrentDir);
155 git_repository_init_options options = GIT_REPOSITORY_INIT_OPTIONS_INIT;
156 options.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE;
157 CAutoRepository repo;
158 ASSERT_EQ(0, git_repository_init_ext(repo.GetPointer(), CUnicodeUtils::GetUTF8(tempdir.GetTempDir()), &options));
159 CAutoConfig config(repo);
160 ASSERT_TRUE(config.IsValid());
161 CStringA path = CUnicodeUtils::GetUTF8(g_Git.m_CurrentDir);
162 path.Replace('\\', '/');
163 EXPECT_EQ(0, git_config_set_string(config, "filter.openssl.clean", path + "/clean_filter_openssl"));
164 EXPECT_EQ(0, git_config_set_string(config, "filter.openssl.smudge", path + "/smudge_filter_openssl"));
165 EXPECT_EQ(0, git_config_set_bool(config, "filter.openssl.required", 1));
166 CString cleanFilterFilename = g_Git.m_CurrentDir + L"\\clean_filter_openssl";
167 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(cleanFilterFilename, L"#!/bin/bash\nopenssl enc -base64 -aes-256-ecb -S FEEDDEADBEEF -k PASS_FIXED"));
168 CString smudgeFilterFilename = g_Git.m_CurrentDir + L"\\smudge_filter_openssl";
169 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(smudgeFilterFilename, L"#!/bin/bash\nopenssl enc -d -base64 -aes-256-ecb -k PASS_FIXED"));
170 EXPECT_EQ(0, git_config_set_string(config, "filter.test.clean", path + "/clean_filter_openssl"));
171 EXPECT_EQ(0, git_config_set_string(config, "filter.test.smudge", path + "/smudge_filter_openssl"));
172 EXPECT_EQ(0, git_config_set_string(config, "filter.test.process", path + "/clean_filter_openssl"));
173 EXPECT_EQ(0, git_config_set_bool(config, "filter.test.required", 1));
175 // need to make sure sh.exe is on PATH
176 g_Git.CheckMsysGitDir();
177 size_t size;
178 _wgetenv_s(&size, nullptr, 0, L"PATH");
179 EXPECT_LT(0U, size);
180 TCHAR* oldEnv = (TCHAR*)alloca(size * sizeof(TCHAR));
181 ASSERT_TRUE(oldEnv);
182 _wgetenv_s(&size, oldEnv, size, L"PATH");
183 _wputenv_s(L"PATH", g_Git.m_Environment.GetEnv(L"PATH"));
184 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(g_Git.m_CurrentDir + L"\\somefile.txt", L"some content"));
186 g_Git.RefreshGitIndex();
188 CString output;
189 EXPECT_EQ(0, g_Git.Run(L"git.exe add somefile.txt", &output, CP_UTF8));
190 EXPECT_STREQ(L"", output);
192 g_Git.RefreshGitIndex();
194 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(g_Git.m_CurrentDir + L"\\somefile.txt", L"some other content"));
196 g_Git.RefreshGitIndex();
198 output.Empty();
199 EXPECT_EQ(0, g_Git.Run(L"git.exe add somefile.txt", &output, CP_UTF8));
200 EXPECT_STREQ(L"", output);
202 g_Git.RefreshGitIndex();
204 // now check with external command filters defined
205 CString attributesFile = g_Git.m_CurrentDir + L"\\.gitattributes";
206 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(attributesFile, L"*.enc filter=openssl\n"));
208 CString encryptedFileOne = g_Git.m_CurrentDir + L"\\1.enc";
209 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(encryptedFileOne, L"This should be encrypted...\nAnd decrypted on the fly\n"));
211 output.Empty();
212 EXPECT_EQ(0, g_Git.Run(L"git.exe add 1.enc", &output, CP_UTF8));
213 if (!g_Git.ms_bCygwinGit) // on AppVeyor with the VS2017 image we get a warning: "WARNING: can't open config file: /usr/local/ssl/openssl.cnf"
214 EXPECT_STREQ(L"", output);
216 WIN32_FILE_ATTRIBUTE_DATA fdata;
217 GetFileAttributesEx(g_Git.m_CurrentDir + L"\\.git\\index", GetFileExInfoStandard, &fdata);
219 g_Git.RefreshGitIndex();
221 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(g_Git.m_CurrentDir + L"\\1.enc", L"some other content"));
223 g_Git.RefreshGitIndex();
225 // need racy timestamp
226 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(g_Git.m_CurrentDir + L"\\1.enc", L"somE other content"));
228 CAutoGeneralHandle handle = ::CreateFile(g_Git.m_CurrentDir + L"\\1.enc", FILE_WRITE_ATTRIBUTES, 0, nullptr, 0, 0, nullptr);
229 SetFileTime(handle, &fdata.ftCreationTime, &fdata.ftLastAccessTime, &fdata.ftLastWriteTime);
232 g_Git.RefreshGitIndex();
234 // now check with external command filters with multi-filter (process) defined
235 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(attributesFile, L"*.enc filter=test\n"));
237 g_Git.RefreshGitIndex();
239 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(g_Git.m_CurrentDir + L"\\1.enc", L"somE other conTentsome other conTentsome other conTen"));
241 g_Git.RefreshGitIndex();
243 // need racy timestamp
244 GetFileAttributesEx(g_Git.m_CurrentDir + L"\\.git\\index", GetFileExInfoStandard, &fdata);
245 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(g_Git.m_CurrentDir + L"\\1.enc", L"some other conTentsome other conTentsome other conTen"));
247 CAutoGeneralHandle handle = ::CreateFile(g_Git.m_CurrentDir + L"\\1.enc", FILE_WRITE_ATTRIBUTES, 0, nullptr, 0, 0, nullptr);
248 SetFileTime(handle, &fdata.ftCreationTime, &fdata.ftLastAccessTime, &fdata.ftLastWriteTime);
251 g_Git.RefreshGitIndex();
253 _wputenv_s(L"PATH", oldEnv);
256 TEST(libgit, IncludeIf)
258 CAutoTempDir tempdir;
259 g_Git.m_bInitialized = false;
260 g_Git.m_IsGitDllInited = false;
261 g_Git.m_IsUseGitDLL = true;
262 g_Git.m_IsUseLibGit2 = false;
263 g_Git.m_IsUseLibGit2_mask = 0;
265 // .git dir
266 CString repoDir = tempdir.GetTempDir() + L"\\RepoWithAInPath";
267 g_Git.m_CurrentDir = repoDir;
268 EXPECT_TRUE(CreateDirectory(repoDir, nullptr));
269 // libgit relies on CWD being set to working tree
270 EXPECT_TRUE(SetCurrentDirectory(repoDir));
272 git_repository_init_options options = GIT_REPOSITORY_INIT_OPTIONS_INIT;
273 options.flags = GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE;
274 CAutoRepository repo;
275 ASSERT_EQ(0, git_repository_init_ext(repo.GetPointer(), CUnicodeUtils::GetUTF8(repoDir), &options));
277 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(repoDir + L"\\.git\\config", L"[core]\n repositoryformatversion = 0\n filemode = false\n bare = false\n logallrefupdates = true\n symlinks = false\n ignorecase = true\n hideDotFiles = dotGitOnly\n[something]\n thevalue = jap\n[includeIf \"gitdir:RepoWithAInPath/**\"]\n path = configA\n[includeIf \"gitdir:RepoWithBInPath/**\"]\n path = configB\n"));
278 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(repoDir + L"\\.git\\configA", L"[somethinga]\n thevalue = jop\n"));
279 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(repoDir + L"\\.git\\configB", L"[somethingb]\n thevalue = jup\n"));
281 EXPECT_STREQ(L"jap", g_Git.GetConfigValue(L"something.thevalue"));
282 EXPECT_STREQ(L"jop",g_Git.GetConfigValue(L"somethinga.thevalue"));
283 EXPECT_STREQ(L"", g_Git.GetConfigValue(L"somethingb.thevalue"));
285 // .git file
286 g_Git.m_bInitialized = false;
287 g_Git.m_IsGitDllInited = false;
288 g_Git.m_IsUseGitDLL = true;
289 repoDir = tempdir.GetTempDir() + L"\\RepoWithBInPath";
290 g_Git.m_CurrentDir = repoDir;
291 EXPECT_TRUE(CreateDirectory(repoDir, nullptr));
292 // libgit relies on CWD being set to working tree
293 EXPECT_TRUE(SetCurrentDirectory(repoDir));
294 EXPECT_TRUE(CStringUtils::WriteStringToTextFile(repoDir + L"\\.git", L"gitdir: ../RepoWithAInPath/.git\n"));
296 EXPECT_STREQ(L"jap", g_Git.GetConfigValue(L"something.thevalue"));
297 EXPECT_STREQ(L"jop", g_Git.GetConfigValue(L"somethinga.thevalue"));
298 EXPECT_STREQ(L"", g_Git.GetConfigValue(L"somethingb.thevalue"));