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