diff mbox series

[v5,02/10] config tests: add "NULL" tests for *_get_value_multi()

Message ID patch-v5-02.10-91a44456327-20230207T154000Z-avarab@gmail.com (mailing list archive)
State Superseded
Headers show
Series config API: make "multi" safe, fix segfaults, propagate "ret" | expand

Commit Message

Ævar Arnfjörð Bjarmason Feb. 7, 2023, 4:10 p.m. UTC
A less well known edge case in the config format is that keys can be
value-less, a shorthand syntax for "true" boolean keys. I.e. these two
are equivalent as far as "--type=bool" is concerned:

	[a]key
	[a]key = true

But as far as our parser is concerned the values for these two are
NULL, and "true". I.e. for a sequence like:

	[a]key=x
	[a]key
	[a]key=y

We get a "struct string_list" with "string" members with ".string"
values of:

	{ "x", NULL, "y" }

This behavior goes back to the initial implementation of
git_config_bool() in 17712991a59 (Add ".git/config" file parser,
2005-10-10).

When parts of the config_set API were tested for in [1] they didn't
add coverage for 3/4 of the "(NULL)" cases handled in
"t/helper/test-config.c". We'd test that case for "get_value", but not
"get_value_multi", "configset_get_value" and
"configset_get_value_multi".

We now cover all of those cases, which in turn expose the details of
how this part of the config API works.

1. 4c715ebb96a (test-config: add tests for the config_set API,
   2014-07-28)

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t1308-config-set.sh | 65 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

Comments

Glen Choo Feb. 9, 2023, 4 a.m. UTC | #1
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:

> +		# Value-less in the middle of a list
> +		cat >"$config" <<-\EOF &&
> +		[a]key=x
> +		[a]key
> +		[a]key=y
> +		EOF
> +		case "$op" in
> +		*_multi)
> +			cat >expect <<-\EOF
> +			x
> +			(NULL)
> +			y
> +			EOF
> +			;;
> +		*)
> +			cat >expect <<-\EOF
> +			y
> +			EOF
> +			;;
> +		esac &&
> +		test-tool config "$op" a.key $file >actual &&
> +		test_cmp expect actual &&

This extra test case makes me feel a bit better about making this DRY,
though the extra "case" statement detracts from the readability a bit.

Maybe if we split the _multi and non-multi cases?

	test_expect_success "multi" '
    # tmp config things

		# Value-less in the middle of a list
		cat >"$config" <<-\EOF &&
		[a]key=x
		[a]key
		[a]key=y
		EOF
    cat >expect <<-\EOF
    x
    (NULL)
    y
    EOF
		test-tool config "$op" a.key $file >actual &&
		test_cmp expect actual &&

		# Value-less at the end of a least (probable typo)
		cat >"$config" <<-\EOF &&
		[a]key=x
		[a]key=y
		[a]key
		EOF
    cat >expect <<-\EOF
    x
    y
    (NULL)
    EOF
		test-tool config "$op" a.key $file >actual &&
		test_cmp expect actual
	'

	test_expect_success "single" '
    # tmp config things

		# Value-less in the middle of a list
		cat >"$config" <<-\EOF &&
		[a]key=x
		[a]key
		[a]key=y
		EOF
    cat >expect <<-\EOF
    y
    EOF
		test-tool config "$op" a.key $file >actual &&
		test_cmp expect actual &&

		# Value-less at the end of a least (probable typo)
		cat >"$config" <<-\EOF &&
		[a]key=x
		[a]key=y
		[a]key
		EOF
    cat >expect <<-\EOF
    (NULL)
    EOF
		test-tool config "$op" a.key $file >actual &&
		test_cmp expect actual
	'

Idk. It does read a bit clearer to me, but I don't feel strongly about
it.

> +		# Value-less at the end of a least

s/least/list
diff mbox series

Patch

diff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh
index b38e158d3b2..4be1ab1147c 100755
--- a/t/t1308-config-set.sh
+++ b/t/t1308-config-set.sh
@@ -146,6 +146,71 @@  test_expect_success 'find multiple values' '
 	check_config get_value_multi case.baz sam bat hask
 '
 
+test_NULL_in_multi () {
+	local op="$1" &&
+	local file="$2" &&
+
+	test_expect_success "$op: NULL value in config${file:+ in $file}" '
+		config="$file" &&
+		if test -z "$config"
+		then
+			config=.git/config &&
+			test_when_finished "mv $config.old $config" &&
+			mv "$config" "$config".old
+		fi &&
+
+		# Value-less in the middle of a list
+		cat >"$config" <<-\EOF &&
+		[a]key=x
+		[a]key
+		[a]key=y
+		EOF
+		case "$op" in
+		*_multi)
+			cat >expect <<-\EOF
+			x
+			(NULL)
+			y
+			EOF
+			;;
+		*)
+			cat >expect <<-\EOF
+			y
+			EOF
+			;;
+		esac &&
+		test-tool config "$op" a.key $file >actual &&
+		test_cmp expect actual &&
+
+		# Value-less at the end of a least
+		cat >"$config" <<-\EOF &&
+		[a]key=x
+		[a]key=y
+		[a]key
+		EOF
+		case "$op" in
+		*_multi)
+			cat >expect <<-\EOF
+			x
+			y
+			(NULL)
+			EOF
+			;;
+		*)
+			cat >expect <<-\EOF
+			(NULL)
+			EOF
+			;;
+		esac &&
+		test-tool config "$op" a.key $file >actual &&
+		test_cmp expect actual
+	'
+}
+
+test_NULL_in_multi "get_value_multi"
+test_NULL_in_multi "configset_get_value" "my.config"
+test_NULL_in_multi "configset_get_value_multi" "my.config"
+
 test_expect_success 'find value from a configset' '
 	cat >config2 <<-\EOF &&
 	[case]