]>
Commit | Line | Data |
---|---|---|
42b34428 | 1 | #include "clar_libgit2.h" |
440e3bae | 2 | #include "patch.h" |
17572f67 | 3 | #include "patch_parse.h" |
42b34428 ET |
4 | |
5 | #include "patch_common.h" | |
6 | ||
94e488a0 | 7 | static void ensure_patch_validity(git_patch *patch) |
42b34428 | 8 | { |
42b34428 ET |
9 | const git_diff_delta *delta; |
10 | char idstr[GIT_OID_HEXSZ+1] = {0}; | |
11 | ||
42b34428 ET |
12 | cl_assert((delta = git_patch_get_delta(patch)) != NULL); |
13 | cl_assert_equal_i(2, delta->nfiles); | |
14 | ||
82175084 | 15 | cl_assert_equal_s(delta->old_file.path, "file.txt"); |
42b34428 ET |
16 | cl_assert(delta->old_file.mode == GIT_FILEMODE_BLOB); |
17 | cl_assert_equal_i(7, delta->old_file.id_abbrev); | |
18 | git_oid_nfmt(idstr, delta->old_file.id_abbrev, &delta->old_file.id); | |
19 | cl_assert_equal_s(idstr, "9432026"); | |
20 | cl_assert_equal_i(0, delta->old_file.size); | |
21 | ||
82175084 | 22 | cl_assert_equal_s(delta->new_file.path, "file.txt"); |
42b34428 ET |
23 | cl_assert(delta->new_file.mode == GIT_FILEMODE_BLOB); |
24 | cl_assert_equal_i(7, delta->new_file.id_abbrev); | |
25 | git_oid_nfmt(idstr, delta->new_file.id_abbrev, &delta->new_file.id); | |
26 | cl_assert_equal_s(idstr, "cd8fd12"); | |
27 | cl_assert_equal_i(0, delta->new_file.size); | |
94e488a0 ET |
28 | } |
29 | ||
e579e0f7 MB |
30 | static void ensure_identical_patch_inout(const char *content) |
31 | { | |
22a2d3d5 UG |
32 | git_buf buf = GIT_BUF_INIT; |
33 | git_patch *patch; | |
34 | ||
35 | cl_git_pass(git_patch_from_buffer(&patch, content, strlen(content), NULL)); | |
36 | cl_git_pass(git_patch_to_buf(&buf, patch)); | |
e579e0f7 | 37 | cl_assert_equal_strn(buf.ptr, content, strlen(content)); |
22a2d3d5 UG |
38 | |
39 | git_patch_free(patch); | |
40 | git_buf_dispose(&buf); | |
41 | } | |
42 | ||
94e488a0 ET |
43 | void test_patch_parse__original_to_change_middle(void) |
44 | { | |
45 | git_patch *patch; | |
42b34428 | 46 | |
94e488a0 ET |
47 | cl_git_pass(git_patch_from_buffer( |
48 | &patch, PATCH_ORIGINAL_TO_CHANGE_MIDDLE, | |
49 | strlen(PATCH_ORIGINAL_TO_CHANGE_MIDDLE), NULL)); | |
50 | ensure_patch_validity(patch); | |
42b34428 ET |
51 | git_patch_free(patch); |
52 | } | |
94e488a0 ET |
53 | |
54 | void test_patch_parse__leading_and_trailing_garbage(void) | |
55 | { | |
56 | git_patch *patch; | |
57 | const char *leading = "This is some leading garbage.\n" | |
58 | "Maybe it's email headers?\n" | |
59 | "\n" | |
60 | PATCH_ORIGINAL_TO_CHANGE_MIDDLE; | |
61 | const char *trailing = PATCH_ORIGINAL_TO_CHANGE_MIDDLE | |
62 | "\n" | |
63 | "This is some trailing garbage.\n" | |
64 | "Maybe it's an email signature?\n"; | |
65 | const char *both = "Here's some leading garbage\n" | |
66 | PATCH_ORIGINAL_TO_CHANGE_MIDDLE | |
67 | "And here's some trailing.\n"; | |
68 | ||
69 | cl_git_pass(git_patch_from_buffer(&patch, leading, strlen(leading), | |
70 | NULL)); | |
71 | ensure_patch_validity(patch); | |
72 | git_patch_free(patch); | |
73 | ||
74 | cl_git_pass(git_patch_from_buffer(&patch, trailing, strlen(trailing), | |
75 | NULL)); | |
76 | ensure_patch_validity(patch); | |
77 | git_patch_free(patch); | |
78 | ||
79 | cl_git_pass(git_patch_from_buffer(&patch, both, strlen(both), | |
80 | NULL)); | |
81 | ensure_patch_validity(patch); | |
82 | git_patch_free(patch); | |
83 | } | |
84 | ||
85 | void test_patch_parse__nonpatches_fail_with_notfound(void) | |
86 | { | |
87 | git_patch *patch; | |
88 | ||
89 | cl_git_fail_with(GIT_ENOTFOUND, | |
90 | git_patch_from_buffer(&patch, PATCH_NOT_A_PATCH, | |
91 | strlen(PATCH_NOT_A_PATCH), NULL)); | |
92 | } | |
93 | ||
94 | void test_patch_parse__invalid_patches_fails(void) | |
95 | { | |
96 | git_patch *patch; | |
97 | ||
98 | cl_git_fail_with(GIT_ERROR, | |
99 | git_patch_from_buffer(&patch, PATCH_CORRUPT_GIT_HEADER, | |
100 | strlen(PATCH_CORRUPT_GIT_HEADER), NULL)); | |
101 | cl_git_fail_with(GIT_ERROR, | |
102 | git_patch_from_buffer(&patch, | |
103 | PATCH_CORRUPT_MISSING_NEW_FILE, | |
104 | strlen(PATCH_CORRUPT_MISSING_NEW_FILE), NULL)); | |
105 | cl_git_fail_with(GIT_ERROR, | |
106 | git_patch_from_buffer(&patch, | |
107 | PATCH_CORRUPT_MISSING_OLD_FILE, | |
108 | strlen(PATCH_CORRUPT_MISSING_OLD_FILE), NULL)); | |
109 | cl_git_fail_with(GIT_ERROR, | |
110 | git_patch_from_buffer(&patch, PATCH_CORRUPT_NO_CHANGES, | |
111 | strlen(PATCH_CORRUPT_NO_CHANGES), NULL)); | |
112 | cl_git_fail_with(GIT_ERROR, | |
113 | git_patch_from_buffer(&patch, | |
114 | PATCH_CORRUPT_MISSING_HUNK_HEADER, | |
115 | strlen(PATCH_CORRUPT_MISSING_HUNK_HEADER), NULL)); | |
116 | } | |
117 | ||
22a2d3d5 UG |
118 | void test_patch_parse__no_newline_at_end_of_new_file(void) |
119 | { | |
120 | ensure_identical_patch_inout(PATCH_APPEND_NO_NL); | |
121 | } | |
122 | ||
123 | void test_patch_parse__no_newline_at_end_of_old_file(void) | |
124 | { | |
125 | ensure_identical_patch_inout(PATCH_APPEND_NO_NL_IN_OLD_FILE); | |
126 | } | |
127 | ||
eae0bfdc | 128 | void test_patch_parse__files_with_whitespaces_succeeds(void) |
22a2d3d5 UG |
129 | { |
130 | ensure_identical_patch_inout(PATCH_NAME_WHITESPACE); | |
131 | } | |
132 | ||
133 | void test_patch_parse__lifetime_of_patch_does_not_depend_on_buffer(void) | |
134 | { | |
e579e0f7 MB |
135 | git_str diff = GIT_STR_INIT; |
136 | git_buf rendered = GIT_BUF_INIT; | |
22a2d3d5 UG |
137 | git_patch *patch; |
138 | ||
e579e0f7 | 139 | cl_git_pass(git_str_sets(&diff, PATCH_ORIGINAL_TO_CHANGE_MIDDLE)); |
22a2d3d5 | 140 | cl_git_pass(git_patch_from_buffer(&patch, diff.ptr, diff.size, NULL)); |
e579e0f7 | 141 | git_str_dispose(&diff); |
22a2d3d5 UG |
142 | |
143 | cl_git_pass(git_patch_to_buf(&rendered, patch)); | |
144 | cl_assert_equal_s(PATCH_ORIGINAL_TO_CHANGE_MIDDLE, rendered.ptr); | |
145 | git_buf_dispose(&rendered); | |
146 | ||
147 | cl_git_pass(git_patch_to_buf(&rendered, patch)); | |
148 | cl_assert_equal_s(PATCH_ORIGINAL_TO_CHANGE_MIDDLE, rendered.ptr); | |
149 | git_buf_dispose(&rendered); | |
150 | ||
151 | git_patch_free(patch); | |
152 | } | |
153 | ||
154 | void test_patch_parse__binary_file_with_missing_paths(void) | |
155 | { | |
156 | git_patch *patch; | |
157 | cl_git_fail(git_patch_from_buffer(&patch, PATCH_BINARY_FILE_WITH_MISSING_PATHS, | |
158 | strlen(PATCH_BINARY_FILE_WITH_MISSING_PATHS), NULL)); | |
159 | } | |
160 | ||
161 | void test_patch_parse__binary_file_with_whitespace_paths(void) | |
162 | { | |
163 | git_patch *patch; | |
164 | cl_git_fail(git_patch_from_buffer(&patch, PATCH_BINARY_FILE_WITH_WHITESPACE_PATHS, | |
165 | strlen(PATCH_BINARY_FILE_WITH_WHITESPACE_PATHS), NULL)); | |
166 | } | |
167 | ||
168 | void test_patch_parse__binary_file_with_empty_quoted_paths(void) | |
169 | { | |
170 | git_patch *patch; | |
171 | cl_git_fail(git_patch_from_buffer(&patch, PATCH_BINARY_FILE_WITH_QUOTED_EMPTY_PATHS, | |
172 | strlen(PATCH_BINARY_FILE_WITH_QUOTED_EMPTY_PATHS), NULL)); | |
173 | } | |
174 | ||
175 | void test_patch_parse__binary_file_path_with_spaces(void) | |
176 | { | |
177 | git_patch *patch; | |
178 | cl_git_fail(git_patch_from_buffer(&patch, PATCH_BINARY_FILE_PATH_WITH_SPACES, | |
179 | strlen(PATCH_BINARY_FILE_PATH_WITH_SPACES), NULL)); | |
180 | } | |
181 | ||
182 | void test_patch_parse__binary_file_path_without_body_paths(void) | |
183 | { | |
184 | git_patch *patch; | |
185 | cl_git_fail(git_patch_from_buffer(&patch, PATCH_BINARY_FILE_PATH_WITHOUT_BODY_PATHS, | |
186 | strlen(PATCH_BINARY_FILE_PATH_WITHOUT_BODY_PATHS), NULL)); | |
187 | } | |
188 | ||
189 | void test_patch_parse__binary_file_with_truncated_delta(void) | |
190 | { | |
191 | git_patch *patch; | |
192 | cl_git_fail(git_patch_from_buffer(&patch, PATCH_BINARY_FILE_WITH_TRUNCATED_DELTA, | |
193 | strlen(PATCH_BINARY_FILE_WITH_TRUNCATED_DELTA), NULL)); | |
194 | cl_assert_equal_s(git_error_last()->message, "truncated binary data at line 5"); | |
195 | } | |
196 | ||
197 | void test_patch_parse__memory_leak_on_multiple_paths(void) | |
198 | { | |
199 | git_patch *patch; | |
200 | cl_git_fail(git_patch_from_buffer(&patch, PATCH_MULTIPLE_OLD_PATHS, strlen(PATCH_MULTIPLE_OLD_PATHS), NULL)); | |
201 | } | |
202 | ||
203 | void test_patch_parse__truncated_no_newline_at_end_of_file(void) | |
204 | { | |
205 | size_t len = strlen(PATCH_APPEND_NO_NL) - strlen("at end of file\n"); | |
206 | const git_diff_line *line; | |
207 | git_patch *patch; | |
208 | ||
209 | cl_git_pass(git_patch_from_buffer(&patch, PATCH_APPEND_NO_NL, len, NULL)); | |
210 | cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 4)); | |
211 | cl_assert_equal_s(line->content, "\\ No newline "); | |
212 | ||
213 | git_patch_free(patch); | |
214 | } | |
215 | ||
216 | void test_patch_parse__line_number_overflow(void) | |
eae0bfdc PP |
217 | { |
218 | git_patch *patch; | |
22a2d3d5 | 219 | cl_git_fail(git_patch_from_buffer(&patch, PATCH_INTMAX_NEW_LINES, strlen(PATCH_INTMAX_NEW_LINES), NULL)); |
eae0bfdc PP |
220 | git_patch_free(patch); |
221 | } |