Message ID | 2c60c4406d4eb1307a32f23604f3ef8e34ad56d6.1708317938.git.gitgitgadget@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | apply: add unit tests for parse_range | expand |
"Philip Peterson via GitGitGadget" <gitgitgadget@gmail.com> writes: > From: Philip Peterson <philip.c.peterson@gmail.com> > > This patchset makes the parse_range function in apply be non-internal > linkage in order to expose to the unit testing framework. In so doing, > because there is another function called parse_range, I gave this one a more > specific name, parse_fragment_range. Other than that, this commit adds > several test cases (positive and negative) for the function. We do not write "I did this, I did that" in our proposed log message. In addition, guidance on the proposed commit log in a handful of sections in Documentation/SubmittingPatches would be helpful. It may probably be a good idea to split this into a preliminary patch that makes a symbol extern (and doing nothing else), and the main patch that adds external caller(s) to the function from a new unit test. It certainly is better than doing nothing and just make it extern, but I am not sure "fragment" is specific enough to make the symbol clearly belong to "apply" API. > diff --git a/apply.c b/apply.c > index 7608e3301ca..199a1150df6 100644 > --- a/apply.c > +++ b/apply.c > @@ -1430,8 +1430,8 @@ static int parse_num(const char *line, unsigned long *p) > return ptr - line; > } > > -static int parse_range(const char *line, int len, int offset, const char *expect, > - unsigned long *p1, unsigned long *p2) > +int parse_fragment_range(const char *line, int len, int offset, const char *expect, > + unsigned long *p1, unsigned long *p2) > { > int digits, ex; Alternatively we could do something like this to make the blast radius of this patch smaller. -static int parse_range(const char *line, int len, int offset, const char *expect, +#define apply_parse_fragment_range parse_range +int parse_range(const char *line, int len, int offset, const char *expect, unsigned long *p1, unsigned long *p2) If not for unit-test, this function has no reason to be extern with such a long name, so it is better to allow internal callers to refer to it with the name that has been good enough for them for the past 19 years since it was introduced in fab2c257 (git-apply: make the diffstat output happen for "--stat" only., 2005-05-26). > diff --git a/apply.h b/apply.h > index 7cd38b1443c..bbc5e3caeb5 100644 > --- a/apply.h > +++ b/apply.h > @@ -187,3 +187,7 @@ int apply_all_patches(struct apply_state *state, > int options); > > #endif > + > + > +int parse_fragment_range(const char *line, int len, int offset, const char *expect, > + unsigned long *p1, unsigned long *p2); This is wrong. The #endif is about avoiding double inclusion of this header file and any new declaration must go before it. > diff --git a/t/unit-tests/t-apply.c b/t/unit-tests/t-apply.c > new file mode 100644 This should go to the next patch.
Hi, Thanks for the tips. I am confused about the change request though: > Alternatively we could do something like this to make the blast > radius of this patch smaller. > > -static int parse_range(const char *line, int len, int offset, const char *expect, > +#define apply_parse_fragment_range parse_range > +int parse_range(const char *line, int len, int offset, const char *expect, > unsigned long *p1, unsigned long *p2) From what I understand, this still creates a new extern symbol called parse_range. The hope was to avoid creating a new symbol with a generic name that someone might start to consume, because if they did start consuming that symbol, it would be a burden on them when we eventually have to rename it due to the conflict with the other symbol currently called parse_range in add-patch.c, which we might also want to add unit tests for later. Is it not preferable to just rename it now, before it becomes extern? Cheers, Phil On Mon, Feb 19, 2024 at 4:35 PM Junio C Hamano <gitster@pobox.com> wrote: > > "Philip Peterson via GitGitGadget" <gitgitgadget@gmail.com> writes: > > > From: Philip Peterson <philip.c.peterson@gmail.com> > > > > This patchset makes the parse_range function in apply be non-internal > > linkage in order to expose to the unit testing framework. In so doing, > > because there is another function called parse_range, I gave this one a more > > specific name, parse_fragment_range. Other than that, this commit adds > > several test cases (positive and negative) for the function. > > We do not write "I did this, I did that" in our proposed log > message. In addition, guidance on the proposed commit log in a > handful of sections in Documentation/SubmittingPatches would be > helpful. > > It may probably be a good idea to split this into a preliminary > patch that makes a symbol extern (and doing nothing else), and > the main patch that adds external caller(s) to the function from > a new unit test. > > It certainly is better than doing nothing and just make it extern, > but I am not sure "fragment" is specific enough to make the symbol > clearly belong to "apply" API. > > > diff --git a/apply.c b/apply.c > > index 7608e3301ca..199a1150df6 100644 > > --- a/apply.c > > +++ b/apply.c > > @@ -1430,8 +1430,8 @@ static int parse_num(const char *line, unsigned long *p) > > return ptr - line; > > } > > > > -static int parse_range(const char *line, int len, int offset, const char *expect, > > - unsigned long *p1, unsigned long *p2) > > +int parse_fragment_range(const char *line, int len, int offset, const char *expect, > > + unsigned long *p1, unsigned long *p2) > > { > > int digits, ex; > > Alternatively we could do something like this to make the blast > radius of this patch smaller. > > -static int parse_range(const char *line, int len, int offset, const char *expect, > +#define apply_parse_fragment_range parse_range > +int parse_range(const char *line, int len, int offset, const char *expect, > unsigned long *p1, unsigned long *p2) > > If not for unit-test, this function has no reason to be extern with > such a long name, so it is better to allow internal callers to refer > to it with the name that has been good enough for them for the past > 19 years since it was introduced in fab2c257 (git-apply: make the > diffstat output happen for "--stat" only., 2005-05-26). > > > diff --git a/apply.h b/apply.h > > index 7cd38b1443c..bbc5e3caeb5 100644 > > --- a/apply.h > > +++ b/apply.h > > @@ -187,3 +187,7 @@ int apply_all_patches(struct apply_state *state, > > int options); > > > > #endif > > + > > + > > +int parse_fragment_range(const char *line, int len, int offset, const char *expect, > > + unsigned long *p1, unsigned long *p2); > > This is wrong. The #endif is about avoiding double inclusion of > this header file and any new declaration must go before it. > > > diff --git a/t/unit-tests/t-apply.c b/t/unit-tests/t-apply.c > > new file mode 100644 > > This should go to the next patch.
Philip <philip.c.peterson@gmail.com> writes: > On Mon, Feb 19, 2024 at 4:35 PM Junio C Hamano <gitster@pobox.com> wrote: >> >> "Philip Peterson via GitGitGadget" <gitgitgadget@gmail.com> writes: It's quite a blast from a long time ago that I no longer remember. >> Alternatively we could do something like this to make the blast >> radius of this patch smaller. >> >> -static int parse_range(const char *line, int len, int offset, const char *expect, >> +#define apply_parse_fragment_range parse_range >> +int parse_range(const char *line, int len, int offset, const char *expect, >> unsigned long *p1, unsigned long *p2) > > From what I understand, this still creates a new extern symbol > called parse_range. Sorry, I misspoke. The direction of #define is the other way around. That is, we may have to give the function a name that is overly long because it needs to be externally linkable only to support for your test, but we would want to locally rename that long name down to the name currently used by the primary callers of that function, so that the patch does not have to touch these existing calling sites. After all, this function is a small implementation detail and not a part of the official apply.c API, and the only reason why we are making it extern is because some new tests want to link with it from the side. So, in the <apply.h> header file you'll do /* * exposed only for tests; do not call this as it not * a part of the API */ extern int apply_parse_fragment_range(...); and then in the original file that used to have "static int parse_range(...)", you'd add #define parse_range apply_parse_fragment_range near the top, after the header files are included. Thanks.
diff --git a/Makefile b/Makefile index 15990ff3122..369092aedfe 100644 --- a/Makefile +++ b/Makefile @@ -1339,6 +1339,7 @@ THIRD_PARTY_SOURCES += compat/regex/% THIRD_PARTY_SOURCES += sha1collisiondetection/% THIRD_PARTY_SOURCES += sha1dc/% +UNIT_TEST_PROGRAMS += t-apply UNIT_TEST_PROGRAMS += t-basic UNIT_TEST_PROGRAMS += t-mem-pool UNIT_TEST_PROGRAMS += t-strbuf diff --git a/apply.c b/apply.c index 7608e3301ca..199a1150df6 100644 --- a/apply.c +++ b/apply.c @@ -1430,8 +1430,8 @@ static int parse_num(const char *line, unsigned long *p) return ptr - line; } -static int parse_range(const char *line, int len, int offset, const char *expect, - unsigned long *p1, unsigned long *p2) +int parse_fragment_range(const char *line, int len, int offset, const char *expect, + unsigned long *p1, unsigned long *p2) { int digits, ex; @@ -1530,8 +1530,8 @@ static int parse_fragment_header(const char *line, int len, struct fragment *fra return -1; /* Figure out the number of lines in a fragment */ - offset = parse_range(line, len, 4, " +", &fragment->oldpos, &fragment->oldlines); - offset = parse_range(line, len, offset, " @@", &fragment->newpos, &fragment->newlines); + offset = parse_fragment_range(line, len, 4, " +", &fragment->oldpos, &fragment->oldlines); + offset = parse_fragment_range(line, len, offset, " @@", &fragment->newpos, &fragment->newlines); return offset; } diff --git a/apply.h b/apply.h index 7cd38b1443c..bbc5e3caeb5 100644 --- a/apply.h +++ b/apply.h @@ -187,3 +187,7 @@ int apply_all_patches(struct apply_state *state, int options); #endif + + +int parse_fragment_range(const char *line, int len, int offset, const char *expect, + unsigned long *p1, unsigned long *p2); diff --git a/t/unit-tests/t-apply.c b/t/unit-tests/t-apply.c new file mode 100644 index 00000000000..ff0abfb2e0b --- /dev/null +++ b/t/unit-tests/t-apply.c @@ -0,0 +1,67 @@ +#include "test-lib.h" +#include "apply.h" + +#define FAILURE -1 + +static void setup_static(const char *line, int len, int offset, + const char *expect, int assert_result, + unsigned long assert_p1, + unsigned long assert_p2) +{ + unsigned long p1 = 9999; + unsigned long p2 = 9999; + int result = parse_fragment_range(line, len, offset, expect, &p1, &p2); + check_int(result, ==, assert_result); + check_int(p1, ==, assert_p1); + check_int(p2, ==, assert_p2); +} + +int cmd_main(int argc, const char **argv) +{ + char* text; + int expected_result; + + /* Success */ + text = "@@ -4,4 +"; + expected_result = 9; + TEST(setup_static(text, strlen(text), 4, " +", expected_result, 4, 4), + "well-formed range"); + + text = "@@ -4 +8 @@"; + expected_result = 7; + TEST(setup_static(text, strlen(text), 4, " +", expected_result, 4, 1), + "non-comma range"); + + /* Failure */ + text = "@@ -X,4 +"; + expected_result = FAILURE; + TEST(setup_static(text, strlen(text), 4, " +", expected_result, 9999, 9999), + "non-digit range (first coordinate)"); + + text = "@@ -4,X +"; + expected_result = FAILURE; + TEST(setup_static(text, strlen(text), 4, " +", expected_result, 4, 1), // p2 is 1, a little strange but not catastrophic + "non-digit range (second coordinate)"); + + text = "@@ -4,4 -"; + expected_result = FAILURE; + TEST(setup_static(text, strlen(text), 4, " +", expected_result, 4, 4), + "non-expected trailing text"); + + text = "@@ -4,4"; + expected_result = FAILURE; + TEST(setup_static(text, strlen(text), 4, " +", expected_result, 4, 4), + "not long enough for expected trailing text"); + + text = "@@ -4,4"; + expected_result = FAILURE; + TEST(setup_static(text, strlen(text), 7, " +", expected_result, 9999, 9999), + "not long enough for offset"); + + text = "@@ -4,4"; + expected_result = FAILURE; + TEST(setup_static(text, strlen(text), -1, " +", expected_result, 9999, 9999), + "negative offset"); + + return test_done(); +}