drivers.c 9.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#include "clar_libgit2.h"
#include "diff_helpers.h"
#include "repository.h"
#include "diff_driver.h"

static git_repository *g_repo = NULL;

void test_diff_drivers__initialize(void)
{
}

void test_diff_drivers__cleanup(void)
{
	cl_git_sandbox_cleanup();
	g_repo = NULL;
}

18
static void overwrite_filemode(const char *expected, git_buf *actual)
19
{
20 21 22 23 24 25 26 27 28
	size_t offset;
	char *found;

	found = strstr(expected, "100644");
	if (!found)
		return;

	offset = ((const char *)found) - expected;
	if (actual->size < offset + 6)
29 30
		return;

31 32
	if (memcmp(&actual->ptr[offset], "100644", 6) != 0)
		memcpy(&actual->ptr[offset], "100644", 6);
33 34
}

35 36
void test_diff_drivers__patterns(void)
{
37
	git_config *cfg;
38 39
	const char *one_sha = "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13";
	git_tree *one;
40 41
	git_diff *diff;
	git_patch *patch;
42
	git_buf actual = GIT_BUF_INIT;
43 44 45 46 47 48 49 50 51 52 53 54
	const char *expected0 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\n--- a/untimely.txt\n+++ b/untimely.txt\n@@ -22,3 +22,5 @@ Comes through the blood of the vanguards who\n   dreamed--too soon--it had sounded.\r\n \r\n                 -- Rudyard Kipling\r\n+\r\n+Some new stuff\r\n";
	const char *expected1 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\nBinary files a/untimely.txt and b/untimely.txt differ\n";
	const char *expected2 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\n--- a/untimely.txt\n+++ b/untimely.txt\n@@ -22,3 +22,5 @@ Heaven delivers on earth the Hour that cannot be\n   dreamed--too soon--it had sounded.\r\n \r\n                 -- Rudyard Kipling\r\n+\r\n+Some new stuff\r\n";

	g_repo = cl_git_sandbox_init("renames");

	one = resolve_commit_oid_to_tree(g_repo, one_sha);

	/* no diff */

	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
	cl_assert_equal_i(0, (int)git_diff_num_deltas(diff));
55
	git_diff_free(diff);
56 57 58 59 60 61 62 63

	/* default diff */

	cl_git_append2file("renames/untimely.txt", "\r\nSome new stuff\r\n");

	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));

Russell Belfer committed
64
	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
65 66
	cl_git_pass(git_patch_to_buf(&actual, patch));
	cl_assert_equal_s(expected0, actual.ptr);
67

68
	git_buf_dispose(&actual);
69 70
	git_patch_free(patch);
	git_diff_free(diff);
71 72 73 74 75 76 77 78

	/* attribute diff set to false */

	cl_git_rewritefile("renames/.gitattributes", "untimely.txt -diff\n");

	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));

Russell Belfer committed
79
	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
80 81
	cl_git_pass(git_patch_to_buf(&actual, patch));
	cl_assert_equal_s(expected1, actual.ptr);
82

83
	git_buf_dispose(&actual);
84 85
	git_patch_free(patch);
	git_diff_free(diff);
86 87 88 89 90 91 92 93

	/* attribute diff set to unconfigured value (should use default) */

	cl_git_rewritefile("renames/.gitattributes", "untimely.txt diff=kipling0\n");

	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));

Russell Belfer committed
94
	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
95 96
	cl_git_pass(git_patch_to_buf(&actual, patch));
	cl_assert_equal_s(expected0, actual.ptr);
97

98
	git_buf_dispose(&actual);
99 100
	git_patch_free(patch);
	git_diff_free(diff);
101 102 103

	/* let's define that driver */

104 105 106
	cl_git_pass(git_repository_config(&cfg, g_repo));
	cl_git_pass(git_config_set_bool(cfg, "diff.kipling0.binary", 1));
	git_config_free(cfg);
107 108 109 110

	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));

Russell Belfer committed
111
	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
112 113
	cl_git_pass(git_patch_to_buf(&actual, patch));
	cl_assert_equal_s(expected1, actual.ptr);
114

115
	git_buf_dispose(&actual);
116 117
	git_patch_free(patch);
	git_diff_free(diff);
118 119 120 121 122 123

	/* let's use a real driver with some regular expressions */

	git_diff_driver_registry_free(g_repo->diff_drivers);
	g_repo->diff_drivers = NULL;

124 125
	cl_git_pass(git_repository_config(&cfg, g_repo));
	cl_git_pass(git_config_set_bool(cfg, "diff.kipling0.binary", 0));
126
	cl_git_pass(git_config_set_string(cfg, "diff.kipling0.xfuncname", "^H.*$"));
127
	git_config_free(cfg);
128 129 130 131

	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));

Russell Belfer committed
132
	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
133 134
	cl_git_pass(git_patch_to_buf(&actual, patch));
	cl_assert_equal_s(expected2, actual.ptr);
135

136
	git_buf_dispose(&actual);
137 138
	git_patch_free(patch);
	git_diff_free(diff);
139 140 141 142

	git_tree_free(one);
}

143 144 145 146
void test_diff_drivers__long_lines(void)
{
	const char *base = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non nisi ligula. Ut viverra enim sed lobortis suscipit.\nPhasellus eget erat odio. Praesent at est iaculis, ultricies augue vel, dignissim risus. Suspendisse at nisi quis turpis fringilla rutrum id sit amet nulla.\nNam eget dolor fermentum, aliquet nisl at, convallis tellus. Pellentesque rhoncus erat enim, id porttitor elit euismod quis.\nMauris sollicitudin magna odio, non egestas libero vehicula ut. Etiam et quam velit. Fusce eget libero rhoncus, ultricies felis sit amet, egestas purus.\nAliquam in semper tellus. Pellentesque adipiscing rutrum velit, quis malesuada lacus consequat eget.\n";
	git_index *idx;
147 148
	git_diff *diff;
	git_patch *patch;
149
	git_buf actual = GIT_BUF_INIT;
150 151 152 153 154 155 156 157 158 159 160 161 162 163
	const char *expected = "diff --git a/longlines.txt b/longlines.txt\nindex c1ce6ef..0134431 100644\n--- a/longlines.txt\n+++ b/longlines.txt\n@@ -3,3 +3,5 @@ Phasellus eget erat odio. Praesent at est iaculis, ultricies augue vel, dignissi\n Nam eget dolor fermentum, aliquet nisl at, convallis tellus. Pellentesque rhoncus erat enim, id porttitor elit euismod quis.\n Mauris sollicitudin magna odio, non egestas libero vehicula ut. Etiam et quam velit. Fusce eget libero rhoncus, ultricies felis sit amet, egestas purus.\n Aliquam in semper tellus. Pellentesque adipiscing rutrum velit, quis malesuada lacus consequat eget.\n+newline\n+newline\n";

	g_repo = cl_git_sandbox_init("empty_standard_repo");

	cl_git_mkfile("empty_standard_repo/longlines.txt", base);
	cl_git_pass(git_repository_index(&idx, g_repo));
	cl_git_pass(git_index_add_bypath(idx, "longlines.txt"));
	cl_git_pass(git_index_write(idx));
	git_index_free(idx);

	cl_git_append2file("empty_standard_repo/longlines.txt", "newline\nnewline\n");

	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, NULL));
	cl_assert_equal_sz(1, git_diff_num_deltas(diff));
Russell Belfer committed
164
	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
165
	cl_git_pass(git_patch_to_buf(&actual, patch));
166

167
	/* if chmod not supported, overwrite mode bits since anything is possible */
168
	overwrite_filemode(expected, &actual);
169

170
	cl_assert_equal_s(expected, actual.ptr);
171

172
	git_buf_dispose(&actual);
173 174
	git_patch_free(patch);
	git_diff_free(diff);
175 176
}

177 178 179 180
void test_diff_drivers__builtins(void)
{
	git_diff *diff;
	git_patch *patch;
181 182
	git_str file = GIT_STR_INIT, expected = GIT_STR_INIT;
	git_buf actual = GIT_BUF_INIT;
183
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
184 185 186
	git_vector files = GIT_VECTOR_INIT;
	size_t i;
	char *path, *extension;
187

188
	g_repo = cl_git_sandbox_init("userdiff");
189

190
	cl_git_pass(git_fs_path_dirload(&files, "userdiff/files", 9, 0));
191

192 193 194
	opts.interhunk_lines = 1;
	opts.context_lines = 1;
	opts.pathspec.count = 1;
195

196 197 198 199 200
	git_vector_foreach(&files, i, path) {
		if (git__prefixcmp(path, "files/file."))
			continue;
		extension = path + strlen("files/file.");
		opts.pathspec.strings = &path;
201

202
		/* do diff with no special driver */
203

204 205 206 207
		cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
		cl_assert_equal_sz(1, git_diff_num_deltas(diff));
		cl_git_pass(git_patch_from_diff(&patch, diff, 0));
		cl_git_pass(git_patch_to_buf(&actual, patch));
208

209 210
		git_str_sets(&expected, "userdiff/expected/nodriver/diff.");
		git_str_puts(&expected, extension);
211
		cl_git_pass(git_futils_readbuffer(&expected, expected.ptr));
212

213
		overwrite_filemode(expected.ptr, &actual);
214

215
		cl_assert_equal_s(expected.ptr, actual.ptr);
216

217
		git_buf_dispose(&actual);
218 219
		git_patch_free(patch);
		git_diff_free(diff);
220

221
		/* do diff with driver */
222

223 224
		{
			FILE *fp = fopen("userdiff/.gitattributes", "w");
225
			fprintf(fp, "*.%s diff=%s\n", extension, extension);
226 227
			fclose(fp);
		}
228

229 230 231 232 233
		cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
		cl_assert_equal_sz(1, git_diff_num_deltas(diff));
		cl_git_pass(git_patch_from_diff(&patch, diff, 0));
		cl_git_pass(git_patch_to_buf(&actual, patch));

234 235
		git_str_sets(&expected, "userdiff/expected/driver/diff.");
		git_str_puts(&expected, extension);
236 237 238
		cl_git_pass(git_futils_readbuffer(&expected, expected.ptr));

		overwrite_filemode(expected.ptr, &actual);
239

240
		cl_assert_equal_s(expected.ptr, actual.ptr);
241

242
		git_buf_dispose(&actual);
243 244
		git_patch_free(patch);
		git_diff_free(diff);
245 246

		git__free(path);
247
	}
248

249
	git_buf_dispose(&actual);
250 251
	git_str_dispose(&file);
	git_str_dispose(&expected);
252
	git_vector_free(&files);
253
}
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279

void test_diff_drivers__invalid_pattern(void)
{
	git_config *cfg;
	git_index *idx;
	git_diff *diff;
	git_patch *patch;
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;

	g_repo = cl_git_sandbox_init("userdiff");
	cl_git_mkfile("userdiff/.gitattributes", "*.storyboard diff=storyboard\n");

	cl_git_pass(git_repository_config__weakptr(&cfg, g_repo));
	cl_git_pass(git_config_set_string(cfg, "diff.storyboard.xfuncname", "<!--(.*?)-->"));

	cl_git_mkfile("userdiff/dummy.storyboard", "");
	cl_git_pass(git_repository_index__weakptr(&idx, g_repo));
	cl_git_pass(git_index_add_bypath(idx, "dummy.storyboard"));
	cl_git_mkfile("userdiff/dummy.storyboard", "some content\n");

	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
	cl_git_pass(git_patch_from_diff(&patch, diff, 0));

	git_patch_free(patch);
	git_diff_free(diff);
}