]> git.proxmox.com Git - libgit2.git/blame - tests/libgit2/diff/drivers.c
Merge https://salsa.debian.org/debian/libgit2 into proxmox/bullseye
[libgit2.git] / tests / libgit2 / diff / drivers.c
CommitLineData
42e6cf78
RB
1#include "clar_libgit2.h"
2#include "diff_helpers.h"
3#include "repository.h"
4#include "diff_driver.h"
5
6static git_repository *g_repo = NULL;
42e6cf78
RB
7
8void test_diff_drivers__initialize(void)
9{
10}
11
12void test_diff_drivers__cleanup(void)
13{
42e6cf78
RB
14 cl_git_sandbox_cleanup();
15 g_repo = NULL;
16}
17
9bbc53d6 18static void overwrite_filemode(const char *expected, git_buf *actual)
2c65602e 19{
9bbc53d6
RB
20 size_t offset;
21 char *found;
22
23 found = strstr(expected, "100644");
24 if (!found)
25 return;
26
27 offset = ((const char *)found) - expected;
28 if (actual->size < offset + 6)
2c65602e
RB
29 return;
30
9bbc53d6
RB
31 if (memcmp(&actual->ptr[offset], "100644", 6) != 0)
32 memcpy(&actual->ptr[offset], "100644", 6);
2c65602e
RB
33}
34
42e6cf78
RB
35void test_diff_drivers__patterns(void)
36{
54faddd2 37 git_config *cfg;
42e6cf78
RB
38 const char *one_sha = "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13";
39 git_tree *one;
3ff1d123
RB
40 git_diff *diff;
41 git_patch *patch;
2c65602e 42 git_buf actual = GIT_BUF_INIT;
42e6cf78
RB
43 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";
44 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";
45 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";
46
47 g_repo = cl_git_sandbox_init("renames");
48
49 one = resolve_commit_oid_to_tree(g_repo, one_sha);
50
51 /* no diff */
52
53 cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
54 cl_assert_equal_i(0, (int)git_diff_num_deltas(diff));
3ff1d123 55 git_diff_free(diff);
42e6cf78
RB
56
57 /* default diff */
58
59 cl_git_append2file("renames/untimely.txt", "\r\nSome new stuff\r\n");
60
61 cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
62 cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
63
10672e3e 64 cl_git_pass(git_patch_from_diff(&patch, diff, 0));
2c65602e
RB
65 cl_git_pass(git_patch_to_buf(&actual, patch));
66 cl_assert_equal_s(expected0, actual.ptr);
42e6cf78 67
ac3d33df 68 git_buf_dispose(&actual);
3ff1d123
RB
69 git_patch_free(patch);
70 git_diff_free(diff);
42e6cf78
RB
71
72 /* attribute diff set to false */
73
74 cl_git_rewritefile("renames/.gitattributes", "untimely.txt -diff\n");
75
76 cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
77 cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
78
10672e3e 79 cl_git_pass(git_patch_from_diff(&patch, diff, 0));
2c65602e
RB
80 cl_git_pass(git_patch_to_buf(&actual, patch));
81 cl_assert_equal_s(expected1, actual.ptr);
42e6cf78 82
ac3d33df 83 git_buf_dispose(&actual);
3ff1d123
RB
84 git_patch_free(patch);
85 git_diff_free(diff);
42e6cf78
RB
86
87 /* attribute diff set to unconfigured value (should use default) */
88
89 cl_git_rewritefile("renames/.gitattributes", "untimely.txt diff=kipling0\n");
90
91 cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
92 cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
93
10672e3e 94 cl_git_pass(git_patch_from_diff(&patch, diff, 0));
2c65602e
RB
95 cl_git_pass(git_patch_to_buf(&actual, patch));
96 cl_assert_equal_s(expected0, actual.ptr);
42e6cf78 97
ac3d33df 98 git_buf_dispose(&actual);
3ff1d123
RB
99 git_patch_free(patch);
100 git_diff_free(diff);
42e6cf78
RB
101
102 /* let's define that driver */
103
54faddd2
RB
104 cl_git_pass(git_repository_config(&cfg, g_repo));
105 cl_git_pass(git_config_set_bool(cfg, "diff.kipling0.binary", 1));
106 git_config_free(cfg);
42e6cf78
RB
107
108 cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
109 cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
110
10672e3e 111 cl_git_pass(git_patch_from_diff(&patch, diff, 0));
2c65602e
RB
112 cl_git_pass(git_patch_to_buf(&actual, patch));
113 cl_assert_equal_s(expected1, actual.ptr);
42e6cf78 114
ac3d33df 115 git_buf_dispose(&actual);
3ff1d123
RB
116 git_patch_free(patch);
117 git_diff_free(diff);
42e6cf78
RB
118
119 /* let's use a real driver with some regular expressions */
120
121 git_diff_driver_registry_free(g_repo->diff_drivers);
122 g_repo->diff_drivers = NULL;
123
54faddd2
RB
124 cl_git_pass(git_repository_config(&cfg, g_repo));
125 cl_git_pass(git_config_set_bool(cfg, "diff.kipling0.binary", 0));
b8e86c62 126 cl_git_pass(git_config_set_string(cfg, "diff.kipling0.xfuncname", "^H.*$"));
54faddd2 127 git_config_free(cfg);
42e6cf78
RB
128
129 cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
130 cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
131
10672e3e 132 cl_git_pass(git_patch_from_diff(&patch, diff, 0));
2c65602e
RB
133 cl_git_pass(git_patch_to_buf(&actual, patch));
134 cl_assert_equal_s(expected2, actual.ptr);
42e6cf78 135
ac3d33df 136 git_buf_dispose(&actual);
3ff1d123
RB
137 git_patch_free(patch);
138 git_diff_free(diff);
42e6cf78
RB
139
140 git_tree_free(one);
141}
142
a5f9b5f8
RB
143void test_diff_drivers__long_lines(void)
144{
145 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";
146 git_index *idx;
3ff1d123
RB
147 git_diff *diff;
148 git_patch *patch;
2c65602e 149 git_buf actual = GIT_BUF_INIT;
a5f9b5f8
RB
150 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";
151
152 g_repo = cl_git_sandbox_init("empty_standard_repo");
153
154 cl_git_mkfile("empty_standard_repo/longlines.txt", base);
155 cl_git_pass(git_repository_index(&idx, g_repo));
156 cl_git_pass(git_index_add_bypath(idx, "longlines.txt"));
157 cl_git_pass(git_index_write(idx));
158 git_index_free(idx);
159
160 cl_git_append2file("empty_standard_repo/longlines.txt", "newline\nnewline\n");
161
162 cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, NULL));
163 cl_assert_equal_sz(1, git_diff_num_deltas(diff));
10672e3e 164 cl_git_pass(git_patch_from_diff(&patch, diff, 0));
2c65602e 165 cl_git_pass(git_patch_to_buf(&actual, patch));
a5f9b5f8 166
5173ea92 167 /* if chmod not supported, overwrite mode bits since anything is possible */
9bbc53d6 168 overwrite_filemode(expected, &actual);
5173ea92 169
2c65602e 170 cl_assert_equal_s(expected, actual.ptr);
a5f9b5f8 171
ac3d33df 172 git_buf_dispose(&actual);
3ff1d123
RB
173 git_patch_free(patch);
174 git_diff_free(diff);
a5f9b5f8
RB
175}
176
2c65602e
RB
177void test_diff_drivers__builtins(void)
178{
2c65602e
RB
179 git_diff *diff;
180 git_patch *patch;
e579e0f7
MB
181 git_str file = GIT_STR_INIT, expected = GIT_STR_INIT;
182 git_buf actual = GIT_BUF_INIT;
2c65602e 183 git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
082e82db
RB
184 git_vector files = GIT_VECTOR_INIT;
185 size_t i;
186 char *path, *extension;
2c65602e 187
027b8eda 188 g_repo = cl_git_sandbox_init("userdiff");
2c65602e 189
e579e0f7 190 cl_git_pass(git_fs_path_dirload(&files, "userdiff/files", 9, 0));
082e82db 191
027b8eda
RB
192 opts.interhunk_lines = 1;
193 opts.context_lines = 1;
194 opts.pathspec.count = 1;
2c65602e 195
082e82db
RB
196 git_vector_foreach(&files, i, path) {
197 if (git__prefixcmp(path, "files/file."))
198 continue;
199 extension = path + strlen("files/file.");
200 opts.pathspec.strings = &path;
2c65602e 201
027b8eda 202 /* do diff with no special driver */
2c65602e 203
027b8eda
RB
204 cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
205 cl_assert_equal_sz(1, git_diff_num_deltas(diff));
206 cl_git_pass(git_patch_from_diff(&patch, diff, 0));
207 cl_git_pass(git_patch_to_buf(&actual, patch));
2c65602e 208
e579e0f7
MB
209 git_str_sets(&expected, "userdiff/expected/nodriver/diff.");
210 git_str_puts(&expected, extension);
027b8eda 211 cl_git_pass(git_futils_readbuffer(&expected, expected.ptr));
2c65602e 212
027b8eda 213 overwrite_filemode(expected.ptr, &actual);
2c65602e 214
027b8eda 215 cl_assert_equal_s(expected.ptr, actual.ptr);
2c65602e 216
e579e0f7 217 git_buf_dispose(&actual);
027b8eda
RB
218 git_patch_free(patch);
219 git_diff_free(diff);
2c65602e 220
027b8eda 221 /* do diff with driver */
2c65602e 222
027b8eda
RB
223 {
224 FILE *fp = fopen("userdiff/.gitattributes", "w");
082e82db 225 fprintf(fp, "*.%s diff=%s\n", extension, extension);
027b8eda
RB
226 fclose(fp);
227 }
2c65602e 228
027b8eda
RB
229 cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
230 cl_assert_equal_sz(1, git_diff_num_deltas(diff));
231 cl_git_pass(git_patch_from_diff(&patch, diff, 0));
232 cl_git_pass(git_patch_to_buf(&actual, patch));
233
e579e0f7
MB
234 git_str_sets(&expected, "userdiff/expected/driver/diff.");
235 git_str_puts(&expected, extension);
027b8eda
RB
236 cl_git_pass(git_futils_readbuffer(&expected, expected.ptr));
237
238 overwrite_filemode(expected.ptr, &actual);
2c65602e 239
027b8eda 240 cl_assert_equal_s(expected.ptr, actual.ptr);
2c65602e 241
e579e0f7 242 git_buf_dispose(&actual);
027b8eda
RB
243 git_patch_free(patch);
244 git_diff_free(diff);
082e82db
RB
245
246 git__free(path);
027b8eda 247 }
2c65602e 248
ac3d33df 249 git_buf_dispose(&actual);
e579e0f7
MB
250 git_str_dispose(&file);
251 git_str_dispose(&expected);
082e82db 252 git_vector_free(&files);
2c65602e 253}
e451cd5c
CMN
254
255void test_diff_drivers__invalid_pattern(void)
256{
257 git_config *cfg;
258 git_index *idx;
259 git_diff *diff;
260 git_patch *patch;
261 git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
262
263 g_repo = cl_git_sandbox_init("userdiff");
264 cl_git_mkfile("userdiff/.gitattributes", "*.storyboard diff=storyboard\n");
265
266 cl_git_pass(git_repository_config__weakptr(&cfg, g_repo));
267 cl_git_pass(git_config_set_string(cfg, "diff.storyboard.xfuncname", "<!--(.*?)-->"));
268
269 cl_git_mkfile("userdiff/dummy.storyboard", "");
270 cl_git_pass(git_repository_index__weakptr(&idx, g_repo));
271 cl_git_pass(git_index_add_bypath(idx, "dummy.storyboard"));
272 cl_git_mkfile("userdiff/dummy.storyboard", "some content\n");
273
274 cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
275 cl_git_pass(git_patch_from_diff(&patch, diff, 0));
276
277 git_patch_free(patch);
278 git_diff_free(diff);
279}