| #define DISABLE_SIGN_COMPARE_WARNINGS |
| |
| #include "unit-test.h" |
| #include "trailer.h" |
| |
| struct contents { |
| const char *raw; |
| const char *key; |
| const char *val; |
| }; |
| |
| static void t_trailer_iterator(const char *msg, size_t num_expected, |
| struct contents *contents) |
| { |
| struct trailer_iterator iter; |
| size_t i = 0; |
| |
| trailer_iterator_init(&iter, msg); |
| while (trailer_iterator_advance(&iter)) { |
| if (num_expected) { |
| cl_assert_equal_s(iter.raw, contents[i].raw); |
| cl_assert_equal_s(iter.key.buf, contents[i].key); |
| cl_assert_equal_s(iter.val.buf, contents[i].val); |
| } |
| i++; |
| } |
| trailer_iterator_release(&iter); |
| |
| cl_assert_equal_i(i, num_expected); |
| } |
| |
| void test_trailer__empty_input(void) |
| { |
| struct contents expected_contents[] = { 0 }; |
| t_trailer_iterator("", 0, expected_contents); |
| } |
| |
| void test_trailer__no_newline_start(void) |
| { |
| struct contents expected_contents[] = { 0 }; |
| |
| t_trailer_iterator("Fixes: x\n" |
| "Acked-by: x\n" |
| "Reviewed-by: x\n", |
| 0, |
| expected_contents); |
| } |
| |
| void test_trailer__newline_start(void) |
| { |
| struct contents expected_contents[] = { |
| { |
| .raw = "Fixes: x\n", |
| .key = "Fixes", |
| .val = "x", |
| }, |
| { |
| .raw = "Acked-by: x\n", |
| .key = "Acked-by", |
| .val = "x", |
| }, |
| { |
| .raw = "Reviewed-by: x\n", |
| .key = "Reviewed-by", |
| .val = "x", |
| }, |
| { |
| 0 |
| }, |
| }; |
| |
| t_trailer_iterator("\n" |
| "Fixes: x\n" |
| "Acked-by: x\n" |
| "Reviewed-by: x\n", |
| 3, |
| expected_contents); |
| } |
| |
| void test_trailer__no_body_text(void) |
| { |
| struct contents expected_contents[] = { |
| |
| { |
| .raw = "Fixes: x\n", |
| .key = "Fixes", |
| .val = "x", |
| }, |
| { |
| .raw = "Acked-by: x\n", |
| .key = "Acked-by", |
| .val = "x", |
| }, |
| { |
| .raw = "Reviewed-by: x\n", |
| .key = "Reviewed-by", |
| .val = "x", |
| }, |
| { |
| 0 |
| }, |
| }; |
| |
| t_trailer_iterator("subject: foo bar\n" |
| "\n" |
| "Fixes: x\n" |
| "Acked-by: x\n" |
| "Reviewed-by: x\n", |
| 3, |
| expected_contents); |
| } |
| |
| void test_trailer__body_text_no_divider(void) |
| { |
| struct contents expected_contents[] = { |
| { |
| .raw = "Fixes: x\n", |
| .key = "Fixes", |
| .val = "x", |
| }, |
| { |
| .raw = "Acked-by: x\n", |
| .key = "Acked-by", |
| .val = "x", |
| }, |
| { |
| .raw = "Reviewed-by: x\n", |
| .key = "Reviewed-by", |
| .val = "x", |
| }, |
| { |
| .raw = "Signed-off-by: x\n", |
| .key = "Signed-off-by", |
| .val = "x", |
| }, |
| { |
| 0 |
| }, |
| }; |
| |
| t_trailer_iterator("my subject\n" |
| "\n" |
| "my body which is long\n" |
| "and contains some special\n" |
| "chars like : = ? !\n" |
| "hello\n" |
| "\n" |
| "Fixes: x\n" |
| "Acked-by: x\n" |
| "Reviewed-by: x\n" |
| "Signed-off-by: x\n", |
| 4, |
| expected_contents); |
| } |
| |
| void test_trailer__body_no_divider_2nd_block(void) |
| { |
| struct contents expected_contents[] = { |
| { |
| .raw = "Helped-by: x\n", |
| .key = "Helped-by", |
| .val = "x", |
| }, |
| { |
| .raw = "Signed-off-by: x\n", |
| .key = "Signed-off-by", |
| .val = "x", |
| }, |
| { |
| 0 |
| }, |
| }; |
| |
| t_trailer_iterator("my subject\n" |
| "\n" |
| "my body which is long\n" |
| "and contains some special\n" |
| "chars like : = ? !\n" |
| "hello\n" |
| "\n" |
| "Fixes: x\n" |
| "Acked-by: x\n" |
| "Reviewed-by: x\n" |
| "Signed-off-by: x\n" |
| "\n" |
| /* |
| * Because this is the last trailer block, it takes |
| * precedence over the first one encountered above. |
| */ |
| "Helped-by: x\n" |
| "Signed-off-by: x\n", |
| 2, |
| expected_contents); |
| } |
| |
| void test_trailer__body_and_divider(void) |
| { |
| struct contents expected_contents[] = { |
| { |
| .raw = "Signed-off-by: x\n", |
| .key = "Signed-off-by", |
| .val = "x", |
| }, |
| { |
| 0 |
| }, |
| }; |
| |
| t_trailer_iterator("my subject\n" |
| "\n" |
| "my body which is long\n" |
| "and contains some special\n" |
| "chars like : = ? !\n" |
| "hello\n" |
| "\n" |
| "---\n" |
| "\n" |
| /* |
| * This trailer still counts because the iterator |
| * always ignores the divider. |
| */ |
| "Signed-off-by: x\n", |
| 1, |
| expected_contents); |
| } |
| |
| void test_trailer__non_trailer_in_block(void) |
| { |
| struct contents expected_contents[] = { |
| { |
| .raw = "not a trailer line\n", |
| .key = "not a trailer line", |
| .val = "", |
| }, |
| { |
| .raw = "not a trailer line\n", |
| .key = "not a trailer line", |
| .val = "", |
| }, |
| { |
| .raw = "not a trailer line\n", |
| .key = "not a trailer line", |
| .val = "", |
| }, |
| { |
| .raw = "Signed-off-by: x\n", |
| .key = "Signed-off-by", |
| .val = "x", |
| }, |
| { |
| 0 |
| }, |
| }; |
| |
| t_trailer_iterator("subject: foo bar\n" |
| "\n" |
| /* |
| * Even though this trailer block has a non-trailer line |
| * in it, it's still a valid trailer block because it's |
| * at least 25% trailers and is Git-generated (see |
| * git_generated_prefixes[] in trailer.c). |
| */ |
| "not a trailer line\n" |
| "not a trailer line\n" |
| "not a trailer line\n" |
| "Signed-off-by: x\n", |
| /* |
| * Even though there is only really 1 real "trailer" |
| * (Signed-off-by), we still have 4 trailer objects |
| * because we still want to iterate through the entire |
| * block. |
| */ |
| 4, |
| expected_contents); |
| } |
| |
| void test_trailer__too_many_non_trailers(void) |
| { |
| struct contents expected_contents[] = { 0 }; |
| |
| t_trailer_iterator("subject: foo bar\n" |
| "\n" |
| /* |
| * This block has only 20% trailers, so it's below the |
| * 25% threshold. |
| */ |
| "not a trailer line\n" |
| "not a trailer line\n" |
| "not a trailer line\n" |
| "not a trailer line\n" |
| "Signed-off-by: x\n", |
| 0, |
| expected_contents); |
| } |
| |
| void test_trailer__one_non_trailer_no_git_trailers(void) |
| { |
| struct contents expected_contents[] = { 0 }; |
| |
| t_trailer_iterator("subject: foo bar\n" |
| "\n" |
| /* |
| * This block has only 1 non-trailer out of 10 (IOW, 90% |
| * trailers) but is not considered a trailer block |
| * because the 25% threshold only applies to cases where |
| * there was a Git-generated trailer. |
| */ |
| "Reviewed-by: x\n" |
| "Reviewed-by: x\n" |
| "Reviewed-by: x\n" |
| "Helped-by: x\n" |
| "Helped-by: x\n" |
| "Helped-by: x\n" |
| "Acked-by: x\n" |
| "Acked-by: x\n" |
| "Acked-by: x\n" |
| "not a trailer line\n", |
| 0, |
| expected_contents); |
| } |