test-parse-options: --expect=<string> option to simplify tests

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@pobox.com>

Junio C Hamano committed May 5, 2016 at 14:36 UTC ab6b28b02f4db52ab5bad342592399f2559b4d81
2 files changed +76 -15
t/t0040-parse-options.sh
+1
@@ -45,6 +45,7 @@ Standard options
45 -v, --verbose be verbose
46 -n, --dry-run dry run
47 -q, --quiet be quiet
48 + --expect <string> expected output in the variable dump
49
50 EOF
51
test-parse-options.c
+75 -15
@@ -39,6 +39,61 @@ static int number_callback(const struct option *opt, const char *arg, int unset)
39 return 0;
40 }
41
42 +static int collect_expect(const struct option *opt, const char *arg, int unset)
43 +{
44 + struct string_list *expect;
45 + struct string_list_item *item;
46 + struct strbuf label = STRBUF_INIT;
47 + const char *colon;
48 +
49 + if (!arg || unset)
50 + die("malformed --expect option");
51 +
52 + expect = (struct string_list *)opt->value;
53 + colon = strchr(arg, ':');
54 + if (!colon)
55 + die("malformed --expect option, lacking a colon");
56 + strbuf_add(&label, arg, colon - arg);
57 + item = string_list_insert(expect, strbuf_detach(&label, NULL));
58 + if (item->util)
59 + die("malformed --expect option, duplicate %s", label.buf);
60 + item->util = (void *)arg;
61 + return 0;
62 +}
63 +
64 +__attribute__((format (printf,3,4)))
65 +static void show(struct string_list *expect, int *status, const char *fmt, ...)
66 +{
67 + struct string_list_item *item;
68 + struct strbuf buf = STRBUF_INIT;
69 + va_list args;
70 +
71 + va_start(args, fmt);
72 + strbuf_vaddf(&buf, fmt, args);
73 + va_end(args);
74 +
75 + if (!expect->nr)
76 + printf("%s\n", buf.buf);
77 + else {
78 + char *colon = strchr(buf.buf, ':');
79 + if (!colon)
80 + die("malformed output format, output lacking colon: %s", fmt);
81 + *colon = '\0';
82 + item = string_list_lookup(expect, buf.buf);
83 + *colon = ':';
84 + if (!item)
85 + ; /* not among entries being checked */
86 + else {
87 + if (strcmp((const char *)item->util, buf.buf)) {
88 + printf("-%s\n", (char *)item->util);
89 + printf("+%s\n", buf.buf);
90 + *status = 1;
91 + }
92 + }
93 + }
94 + strbuf_release(&buf);
95 +}
96 +
97 int main(int argc, char **argv)
98 {
99 const char *prefix = "prefix/";
@@ -46,6 +101,7 @@ int main(int argc, char **argv)
101 "test-parse-options <options>",
102 NULL
103 };
104 + struct string_list expect = STRING_LIST_INIT_NODUP;
105 struct option options[] = {
106 OPT_BOOL(0, "yes", &boolean, "get a boolean"),
107 OPT_BOOL('D', "no-doubt", &boolean, "begins with 'no-'"),
@@ -86,34 +142,38 @@ int main(int argc, char **argv)
142 OPT__VERBOSE(&verbose, "be verbose"),
143 OPT__DRY_RUN(&dry_run, "dry run"),
144 OPT__QUIET(&quiet, "be quiet"),
145 + OPT_CALLBACK(0, "expect", &expect, "string",
146 + "expected output in the variable dump",
147 + collect_expect),
148 OPT_END(),
149 };
150 int i;
151 + int ret = 0;
152
153 argc = parse_options(argc, (const char **)argv, prefix, options, usage, 0);
154
155 if (length_cb.called) {
156 const char *arg = length_cb.arg;
157 int unset = length_cb.unset;
98 - printf("Callback: \"%s\", %d\n",
99 - (arg ? arg : "not set"), unset);
158 + show(&expect, &ret, "Callback: \"%s\", %d",
159 + (arg ? arg : "not set"), unset);
160 }
101 - printf("boolean: %d\n", boolean);
102 - printf("integer: %d\n", integer);
103 - printf("magnitude: %lu\n", magnitude);
104 - printf("timestamp: %lu\n", timestamp);
105 - printf("string: %s\n", string ? string : "(not set)");
106 - printf("abbrev: %d\n", abbrev);
107 - printf("verbose: %d\n", verbose);
108 - printf("quiet: %d\n", quiet);
109 - printf("dry run: %s\n", dry_run ? "yes" : "no");
110 - printf("file: %s\n", file ? file : "(not set)");
161 + show(&expect, &ret, "boolean: %d", boolean);
162 + show(&expect, &ret, "integer: %d", integer);
163 + show(&expect, &ret, "magnitude: %lu", magnitude);
164 + show(&expect, &ret, "timestamp: %lu", timestamp);
165 + show(&expect, &ret, "string: %s", string ? string : "(not set)");
166 + show(&expect, &ret, "abbrev: %d", abbrev);
167 + show(&expect, &ret, "verbose: %d", verbose);
168 + show(&expect, &ret, "quiet: %d", quiet);
169 + show(&expect, &ret, "dry run: %s", dry_run ? "yes" : "no");
170 + show(&expect, &ret, "file: %s", file ? file : "(not set)");
171
172 for (i = 0; i < list.nr; i++)
113 - printf("list: %s\n", list.items[i].string);
173 + show(&expect, &ret, "list: %s", list.items[i].string);
174
175 for (i = 0; i < argc; i++)
116 - printf("arg %02d: %s\n", i, argv[i]);
176 + show(&expect, &ret, "arg %02d: %s", i, argv[i]);
177
118 - return 0;
178 + return ret;
179 }