summaryrefslogtreecommitdiff
path: root/tests/checkout/icase.c
blob: 3a6ce2078d7a5f125729b49fc89001bdba26b70f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "clar_libgit2.h"

#include "git2/checkout.h"
#include "path.h"

#ifdef GIT_WIN32
# include <Windows.h>
#endif

static git_repository *repo;
static git_object *obj;
static git_checkout_options checkout_opts;

void test_checkout_icase__initialize(void)
{
	git_oid id;

	repo = cl_git_sandbox_init("testrepo");

	cl_git_pass(git_reference_name_to_id(&id, repo, "refs/heads/dir"));
	cl_git_pass(git_object_lookup(&obj, repo, &id, GIT_OBJ_ANY));

	git_checkout_init_options(&checkout_opts, GIT_CHECKOUT_OPTIONS_VERSION);
	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
}

void test_checkout_icase__cleanup(void)
{
	git_object_free(obj);
	cl_git_sandbox_cleanup();
}

static char *test_realpath(const char *in)
{
#ifdef GIT_WIN32
	HANDLE fh;
	HMODULE kerneldll;
	char *filename;

	typedef DWORD (__stdcall *getfinalpathname)(HANDLE, LPSTR, DWORD, DWORD);
	getfinalpathname getfinalpathfn;

	cl_assert(filename = malloc(MAX_PATH));
	cl_assert(kerneldll = LoadLibrary("kernel32.dll"));
	cl_assert(getfinalpathfn = (getfinalpathname)GetProcAddress(kerneldll, "GetFinalPathNameByHandleA"));

	cl_assert(fh = CreateFileA(in, FILE_READ_ATTRIBUTES | STANDARD_RIGHTS_READ, FILE_SHARE_READ,
		NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL));

	cl_win32_pass(getfinalpathfn(fh, filename, MAX_PATH, VOLUME_NAME_DOS));

	CloseHandle(fh);

	git_path_mkposix(filename);

	return filename;
#else
	return realpath(in, NULL);
#endif
}

static void assert_name_is(const char *expected)
{
	char *actual;
	size_t actual_len, expected_len, start;

	cl_assert(actual = test_realpath(expected));

	expected_len = strlen(expected);
	actual_len = strlen(actual);
	cl_assert(actual_len >= expected_len);

	start = actual_len - expected_len;
	cl_assert_equal_s(expected, actual + start);

	if (start)
		cl_assert_equal_strn("/", actual + (start - 1), 1);

	free(actual);
}

void test_checkout_icase__overwrites_files_for_files(void)
{
	cl_git_write2file("testrepo/NEW.txt", "neue file\n", 10, \
		O_WRONLY | O_CREAT | O_TRUNC, 0644);

	cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
	assert_name_is("testrepo/new.txt");
}

void test_checkout_icase__overwrites_links_for_files(void)
{
	cl_must_pass(p_symlink("../tmp", "testrepo/NEW.txt"));

	cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));

	cl_assert(!git_path_exists("tmp"));
	assert_name_is("testrepo/new.txt");
}

void test_checkout_icase__overwites_folders_for_files(void)
{
	cl_must_pass(p_mkdir("testrepo/NEW.txt", 0777));

	cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));

	assert_name_is("testrepo/new.txt");
	cl_assert(!git_path_isdir("testrepo/new.txt"));
}

void test_checkout_icase__overwrites_files_for_folders(void)
{
	cl_git_write2file("testrepo/A", "neue file\n", 10, \
		O_WRONLY | O_CREAT | O_TRUNC, 0644);

	cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
	assert_name_is("testrepo/a");
	cl_assert(git_path_isdir("testrepo/a"));
}

void test_checkout_icase__overwrites_links_for_folders(void)
{
	cl_must_pass(p_symlink("..", "testrepo/A"));

	cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));

	cl_assert(!git_path_exists("b.txt"));
	assert_name_is("testrepo/a");
}