On Thu, May 5, 2016 at 2:50 PM, Junio C Hamano <gitster@xxxxxxxxx> wrote: > Existing tests in t0040 follow a rather verbose pattern: > > cat >expect <<\EOF > boolean: 0 > integer: 0 > magnitude: 0 > timestamp: 0 > string: (not set) > abbrev: 7 > verbose: 0 > quiet: 3 > dry run: no > file: (not set) > EOF > > test_expect_success 'multiple quiet levels' ' > test-parse-options -q -q -q >output 2>output.err && > test_must_be_empty output.err && > test_cmp expect output > ' > > But the only thing this test cares about is if "quiet: 3" is in the > output. We should be able to write the above 18 lines with just > four lines, like this: > > test_expect_success 'multiple quiet levels' ' > test-parse-options --expect="quiet: 3" -q -q -q > ' > > Teach the new --expect=<string> option to test-parse-options helper. > > Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> > --- > t/t0040-parse-options.sh | 1 + > test-parse-options.c | 68 +++++++++++++++++++++++++++++++++++++++++++++--- > 2 files changed, 66 insertions(+), 3 deletions(-) > > diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh > index dbaee55..d678fbf 100755 > --- a/t/t0040-parse-options.sh > +++ b/t/t0040-parse-options.sh > @@ -45,6 +45,7 @@ Standard options > -v, --verbose be verbose > -n, --dry-run dry run > -q, --quiet be quiet > + --expect <string> expected output in the variable dump > > EOF > > diff --git a/test-parse-options.c b/test-parse-options.c > index 3db4332..010f3b2 100644 > --- a/test-parse-options.c > +++ b/test-parse-options.c > @@ -14,6 +14,7 @@ static char *string = NULL; > static char *file = NULL; > static int ambiguous; > static struct string_list list; > +static struct string_list expect; > > static struct { > int called; > @@ -40,6 +41,62 @@ static int number_callback(const struct option *opt, const char *arg, int unset) > return 0; > } > > +/* > + * See if expect->string ("label: value") has a line in output that > + * begins with "label:", and if the line in output matches it. > + */ > +static int match_line(struct string_list_item *expect, struct strbuf *output) > +{ > + const char *label = expect->string; > + const char *colon = strchr(label, ':'); > + const char *scan = output->buf; > + size_t label_len, expect_len; > + > + if (!colon) > + die("Malformed --expect value: %s", label); > + label_len = colon - label; > + > + while (scan < output->buf + output->len) { > + const char *next; > + scan = memmem(scan, output->buf + output->len - scan, > + label, label_len); > + if (!scan) > + return 0; > + if (scan == output->buf || scan[-1] == '\n') Does scan[-1] work for the first line? > + break; > + next = strchr(scan + label_len, '\n'); > + if (!next) > + return 0; > + scan = next + 1; > + } > + > + /* > + * scan points at a line that begins with the label we are > + * looking for. Does it match? > + */ > + expect_len = strlen(expect->string); > + > + if (output->buf + output->len <= scan + expect_len) > + return 0; /* value not long enough */ > + if (memcmp(scan, expect->string, expect_len)) > + return 0; /* does not match */ > + > + return (scan + expect_len < output->buf + output->len && > + scan[expect_len] == '\n'); > +} > + > +static int show_expected(struct string_list *list, struct strbuf *output) > +{ > + struct string_list_item *expect; > + int found_mismatch = 0; > + > + for_each_string_list_item(expect, list) { > + if (!match_line(expect, output)) > + found_mismatch = 1; > + } > + return found_mismatch; > +} > + > int main(int argc, char **argv) > { > const char *prefix = "prefix/"; > @@ -87,6 +144,8 @@ int main(int argc, char **argv) > OPT__VERBOSE(&verbose, "be verbose"), > OPT__DRY_RUN(&dry_run, "dry run"), > OPT__QUIET(&quiet, "be quiet"), > + OPT_STRING_LIST(0, "expect", &expect, "string", > + "expected output in the variable dump"), > OPT_END(), > }; > int i; > @@ -117,7 +176,10 @@ int main(int argc, char **argv) > for (i = 0; i < argc; i++) > strbuf_addf(&output, "arg %02d: %s\n", i, argv[i]); > > - printf("%s", output.buf); > - > - return 0; > + if (expect.nr) > + return show_expected(&expect, &output); On a philosophical level this patch series is adding a trailing "|grep $X" for the test-parse-options. I think such a grep pattern is a good thing because it is cheap to implement in unix like environments. This however is a lot of C code for finding specific subsets in the output, so it is not quite cheap. Then we could also go the non-wasteful way and instead check what to add to the strbuf instead of filtering afterwards, i.e. each strbuf_add is guarded by an if (is_interesting_output(...)) strbuf_add(...) > + else { > + printf("%s", output.buf); > + return 0; > + } > } > -- > 2.8.2-505-gdbd0e1d > > -- > To unsubscribe from this list: send the line "unsubscribe git" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html