1 #include "clar_libgit2.h"
3 #include "patch_parse.h"
5 #include "patch_common.h"
7 static void ensure_patch_validity(git_patch
*patch
)
9 const git_diff_delta
*delta
;
10 char idstr
[GIT_OID_HEXSZ
+1] = {0};
12 cl_assert((delta
= git_patch_get_delta(patch
)) != NULL
);
13 cl_assert_equal_i(2, delta
->nfiles
);
15 cl_assert_equal_s(delta
->old_file
.path
, "file.txt");
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
);
22 cl_assert_equal_s(delta
->new_file
.path
, "file.txt");
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
);
30 static void ensure_identical_patch_inout(const char *content
)
32 git_buf buf
= GIT_BUF_INIT
;
35 cl_git_pass(git_patch_from_buffer(&patch
, content
, strlen(content
), NULL
));
36 cl_git_pass(git_patch_to_buf(&buf
, patch
));
37 cl_assert_equal_strn(buf
.ptr
, content
, strlen(content
));
39 git_patch_free(patch
);
40 git_buf_dispose(&buf
);
43 void test_patch_parse__original_to_change_middle(void)
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
);
51 git_patch_free(patch
);
54 void test_patch_parse__leading_and_trailing_garbage(void)
57 const char *leading
= "This is some leading garbage.\n"
58 "Maybe it's email headers?\n"
60 PATCH_ORIGINAL_TO_CHANGE_MIDDLE
;
61 const char *trailing
= PATCH_ORIGINAL_TO_CHANGE_MIDDLE
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";
69 cl_git_pass(git_patch_from_buffer(&patch
, leading
, strlen(leading
),
71 ensure_patch_validity(patch
);
72 git_patch_free(patch
);
74 cl_git_pass(git_patch_from_buffer(&patch
, trailing
, strlen(trailing
),
76 ensure_patch_validity(patch
);
77 git_patch_free(patch
);
79 cl_git_pass(git_patch_from_buffer(&patch
, both
, strlen(both
),
81 ensure_patch_validity(patch
);
82 git_patch_free(patch
);
85 void test_patch_parse__nonpatches_fail_with_notfound(void)
89 cl_git_fail_with(GIT_ENOTFOUND
,
90 git_patch_from_buffer(&patch
, PATCH_NOT_A_PATCH
,
91 strlen(PATCH_NOT_A_PATCH
), NULL
));
94 void test_patch_parse__invalid_patches_fails(void)
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
));
118 void test_patch_parse__no_newline_at_end_of_new_file(void)
120 ensure_identical_patch_inout(PATCH_APPEND_NO_NL
);
123 void test_patch_parse__no_newline_at_end_of_old_file(void)
125 ensure_identical_patch_inout(PATCH_APPEND_NO_NL_IN_OLD_FILE
);
128 void test_patch_parse__files_with_whitespaces_succeeds(void)
130 ensure_identical_patch_inout(PATCH_NAME_WHITESPACE
);
133 void test_patch_parse__lifetime_of_patch_does_not_depend_on_buffer(void)
135 git_str diff
= GIT_STR_INIT
;
136 git_buf rendered
= GIT_BUF_INIT
;
139 cl_git_pass(git_str_sets(&diff
, PATCH_ORIGINAL_TO_CHANGE_MIDDLE
));
140 cl_git_pass(git_patch_from_buffer(&patch
, diff
.ptr
, diff
.size
, NULL
));
141 git_str_dispose(&diff
);
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
);
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
);
151 git_patch_free(patch
);
154 void test_patch_parse__binary_file_with_missing_paths(void)
157 cl_git_fail(git_patch_from_buffer(&patch
, PATCH_BINARY_FILE_WITH_MISSING_PATHS
,
158 strlen(PATCH_BINARY_FILE_WITH_MISSING_PATHS
), NULL
));
161 void test_patch_parse__binary_file_with_whitespace_paths(void)
164 cl_git_fail(git_patch_from_buffer(&patch
, PATCH_BINARY_FILE_WITH_WHITESPACE_PATHS
,
165 strlen(PATCH_BINARY_FILE_WITH_WHITESPACE_PATHS
), NULL
));
168 void test_patch_parse__binary_file_with_empty_quoted_paths(void)
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
));
175 void test_patch_parse__binary_file_path_with_spaces(void)
178 cl_git_fail(git_patch_from_buffer(&patch
, PATCH_BINARY_FILE_PATH_WITH_SPACES
,
179 strlen(PATCH_BINARY_FILE_PATH_WITH_SPACES
), NULL
));
182 void test_patch_parse__binary_file_path_without_body_paths(void)
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
));
189 void test_patch_parse__binary_file_with_truncated_delta(void)
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");
197 void test_patch_parse__memory_leak_on_multiple_paths(void)
200 cl_git_fail(git_patch_from_buffer(&patch
, PATCH_MULTIPLE_OLD_PATHS
, strlen(PATCH_MULTIPLE_OLD_PATHS
), NULL
));
203 void test_patch_parse__truncated_no_newline_at_end_of_file(void)
205 size_t len
= strlen(PATCH_APPEND_NO_NL
) - strlen("at end of file\n");
206 const git_diff_line
*line
;
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 ");
213 git_patch_free(patch
);
216 void test_patch_parse__line_number_overflow(void)
219 cl_git_fail(git_patch_from_buffer(&patch
, PATCH_INTMAX_NEW_LINES
, strlen(PATCH_INTMAX_NEW_LINES
), NULL
));
220 git_patch_free(patch
);