shithub: furgit

Download patch

ref: c67ae1bdeeac3752c2df1fa47a013353b3b508bd
parent: 3d98cec9e2d8b93517e38f46410d28d0b6308d3e
author: Runxi Yu <me@runxiyu.org>
date: Wed Mar 4 09:14:03 EST 2026

config: More tests for each algorithm

--- a/config/config_test.go
+++ b/config/config_test.go
@@ -467,88 +467,94 @@
 	}
 }
 
-func TestConfigEOFAfterKeyAgainstGit(t *testing.T) {
+func TestConfigEOFAfterKeyAgainstGit(t *testing.T) { //nolint:dupl
 	t.Parallel()
-	testRepo := testgit.NewRepo(t, testgit.RepoOptions{ObjectFormat: objectid.AlgorithmSHA1, Bare: true})
-	cfgPath := filepath.Join(testRepo.Dir(), "config")
+	testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { //nolint:thelper
+		testRepo := testgit.NewRepo(t, testgit.RepoOptions{ObjectFormat: algo, Bare: true})
+		cfgPath := filepath.Join(testRepo.Dir(), "config")
 
-	cfgData := []byte("[Core]BAre")
+		cfgData := []byte("[Core]BAre")
 
-	err := os.WriteFile(cfgPath, cfgData, 0o600)
-	if err != nil {
-		t.Fatalf("failed to write config: %v", err)
-	}
+		err := os.WriteFile(cfgPath, cfgData, 0o600)
+		if err != nil {
+			t.Fatalf("failed to write config: %v", err)
+		}
 
-	gitValue, gitErr := gitConfigGetE(testRepo, "Core.BAre")
-	furConfig, furErr := config.ParseConfig(bytes.NewReader(cfgData))
+		gitValue, gitErr := gitConfigGetE(testRepo, "Core.BAre")
+		furConfig, furErr := config.ParseConfig(bytes.NewReader(cfgData))
 
-	if (gitErr == nil) != (furErr == nil) {
-		t.Fatalf("git: %v\nfur: %v", gitErr, furErr)
-	}
+		if (gitErr == nil) != (furErr == nil) {
+			t.Fatalf("git: %v\nfur: %v", gitErr, furErr)
+		}
 
-	if furErr != nil {
-		return
-	}
+		if furErr != nil {
+			return
+		}
 
-	if got := lookupValue(furConfig, "Core", "", "BAre"); got != gitValue {
-		t.Fatalf("git: %q\nfur: %q", gitValue, got)
-	}
+		if got := lookupValue(furConfig, "Core", "", "BAre"); got != gitValue {
+			t.Fatalf("git: %q\nfur: %q", gitValue, got)
+		}
+	})
 }
 
-func TestConfigNULValueAgainstGit(t *testing.T) {
+func TestConfigNULValueAgainstGit(t *testing.T) { //nolint:dupl
 	t.Parallel()
-	testRepo := testgit.NewRepo(t, testgit.RepoOptions{ObjectFormat: objectid.AlgorithmSHA1, Bare: true})
-	cfgPath := filepath.Join(testRepo.Dir(), "config")
+	testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { //nolint:thelper
+		testRepo := testgit.NewRepo(t, testgit.RepoOptions{ObjectFormat: algo, Bare: true})
+		cfgPath := filepath.Join(testRepo.Dir(), "config")
 
-	cfgData := []byte("[Core]BAre=\x00")
+		cfgData := []byte("[Core]BAre=\x00")
 
-	err := os.WriteFile(cfgPath, cfgData, 0o600)
-	if err != nil {
-		t.Fatalf("failed to write config: %v", err)
-	}
+		err := os.WriteFile(cfgPath, cfgData, 0o600)
+		if err != nil {
+			t.Fatalf("failed to write config: %v", err)
+		}
 
-	gitValue, gitErr := gitConfigGetE(testRepo, "Core.BAre")
-	furConfig, furErr := config.ParseConfig(bytes.NewReader(cfgData))
+		gitValue, gitErr := gitConfigGetE(testRepo, "Core.BAre")
+		furConfig, furErr := config.ParseConfig(bytes.NewReader(cfgData))
 
-	if (gitErr == nil) != (furErr == nil) {
-		t.Fatalf("git: %v\nfur: %v", gitErr, furErr)
-	}
+		if (gitErr == nil) != (furErr == nil) {
+			t.Fatalf("git: %v\nfur: %v", gitErr, furErr)
+		}
 
-	if furErr != nil {
-		return
-	}
+		if furErr != nil {
+			return
+		}
 
-	if got := lookupValue(furConfig, "Core", "", "BAre"); got != gitValue {
-		t.Fatalf("git: %q\nfur: %q", gitValue, got)
-	}
+		if got := lookupValue(furConfig, "Core", "", "BAre"); got != gitValue {
+			t.Fatalf("git: %q\nfur: %q", gitValue, got)
+		}
+	})
 }
 
-func TestConfigCarriageReturnSeparatorAgainstGit(t *testing.T) {
+func TestConfigCarriageReturnSeparatorAgainstGit(t *testing.T) { //nolint:dupl
 	t.Parallel()
-	testRepo := testgit.NewRepo(t, testgit.RepoOptions{ObjectFormat: objectid.AlgorithmSHA1, Bare: true})
-	cfgPath := filepath.Join(testRepo.Dir(), "config")
+	testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { //nolint:thelper
+		testRepo := testgit.NewRepo(t, testgit.RepoOptions{ObjectFormat: algo, Bare: true})
+		cfgPath := filepath.Join(testRepo.Dir(), "config")
 
-	cfgData := []byte("[Core \"sub\"]\rBAre")
+		cfgData := []byte("[Core \"sub\"]\rBAre")
 
-	err := os.WriteFile(cfgPath, cfgData, 0o600)
-	if err != nil {
-		t.Fatalf("failed to write config: %v", err)
-	}
+		err := os.WriteFile(cfgPath, cfgData, 0o600)
+		if err != nil {
+			t.Fatalf("failed to write config: %v", err)
+		}
 
-	gitValue, gitErr := gitConfigGetE(testRepo, "Core.sub.BAre")
-	furConfig, furErr := config.ParseConfig(bytes.NewReader(cfgData))
+		gitValue, gitErr := gitConfigGetE(testRepo, "Core.sub.BAre")
+		furConfig, furErr := config.ParseConfig(bytes.NewReader(cfgData))
 
-	if (gitErr == nil) != (furErr == nil) {
-		t.Fatalf("git: %v\nfur: %v", gitErr, furErr)
-	}
+		if (gitErr == nil) != (furErr == nil) {
+			t.Fatalf("git: %v\nfur: %v", gitErr, furErr)
+		}
 
-	if furErr != nil {
-		return
-	}
+		if furErr != nil {
+			return
+		}
 
-	if got := lookupValue(furConfig, "Core", "sub", "BAre"); got != gitValue {
-		t.Fatalf("git: %q\nfur: %q", gitValue, got)
-	}
+		if got := lookupValue(furConfig, "Core", "sub", "BAre"); got != gitValue {
+			t.Fatalf("git: %q\nfur: %q", gitValue, got)
+		}
+	})
 }
 
 func FuzzConfig(f *testing.F) {
@@ -556,54 +562,72 @@
 	f.Add([]byte("[core]\nbare = true\n[core/invalid]"), "core.bare")
 	f.Add([]byte("[core \"sub\"]\nbare = true"), "core.sub.bare")
 
-	testRepo := testgit.NewRepo(f, testgit.RepoOptions{ObjectFormat: objectid.AlgorithmSHA1, Bare: true})
-	cfgPath := filepath.Join(testRepo.Dir(), "config")
+	type fuzzRepoState struct {
+		repo    *testgit.TestRepo
+		cfgPath string
+	}
 
-	f.Fuzz(func(t *testing.T, cfgData []byte, gitKey string) {
-		err := os.WriteFile(cfgPath, cfgData, 0o600)
-		if err != nil {
-			t.Fatalf("failed to write config: %v", err)
+	repos := make(map[objectid.Algorithm]fuzzRepoState, len(objectid.SupportedAlgorithms()))
+	for _, algo := range objectid.SupportedAlgorithms() {
+		testRepo := testgit.NewRepo(f, testgit.RepoOptions{ObjectFormat: algo, Bare: true})
+		repos[algo] = fuzzRepoState{
+			repo:    testRepo,
+			cfgPath: filepath.Join(testRepo.Dir(), "config"),
 		}
+	}
 
-		gitValue, gitErr := gitConfigGetE(testRepo, gitKey)
+	f.Fuzz(func(t *testing.T, cfgData []byte, gitKey string) {
+		for _, algo := range objectid.SupportedAlgorithms() {
+			state, ok := repos[algo]
+			if !ok {
+				t.Fatalf("missing fuzz repo state for %v", algo)
+			}
 
-		furConfig, furErr := config.ParseConfig(bytes.NewReader(cfgData))
-		if furErr == nil && furConfig == nil {
-			t.Fatalf("ParseConfig returned nil config with nil error")
-		}
-
-		sameErr := (gitErr == nil) == (furErr == nil)
-		if !sameErr {
-			if furErr == nil {
-				return
+			err := os.WriteFile(state.cfgPath, cfgData, 0o600)
+			if err != nil {
+				t.Fatalf("failed to write config: %v", err)
 			}
 
-			t.Fatalf("git: %v\nfur: %v", gitErr, furErr)
-		}
+			gitValue, gitErr := gitConfigGetE(state.repo, gitKey)
 
-		if furErr == nil {
-			parts := strings.SplitN(gitKey, ".", 3)
-			furSection := parts[0]
+			furConfig, furErr := config.ParseConfig(bytes.NewReader(cfgData))
+			if furErr == nil && furConfig == nil {
+				t.Fatalf("ParseConfig returned nil config with nil error")
+			}
 
-			var furSubsection, furKey string
+			sameErr := (gitErr == nil) == (furErr == nil)
+			if !sameErr {
+				if furErr == nil {
+					return
+				}
 
-			switch len(parts) {
-			case 1:
-			case 2:
-				furKey = parts[1]
-			case 3:
-				furSubsection = parts[1]
-				furKey = parts[2]
-			default:
-				t.Fatalf("unexpected split(%q): %v", gitKey, parts)
+				t.Fatalf("git: %v\nfur: %v", gitErr, furErr)
 			}
 
-			furValue := lookupValue(furConfig, furSection, furSubsection, furKey)
-			if gitValue != furValue {
-				t.Fatalf(
-					"key: %v (%v.%v.%v)\ngit: %q\nfur: %q",
-					gitKey, furSection, furSubsection, furKey, gitValue, furValue,
-				)
+			if furErr == nil {
+				parts := strings.SplitN(gitKey, ".", 3)
+				furSection := parts[0]
+
+				var furSubsection, furKey string
+
+				switch len(parts) {
+				case 1:
+				case 2:
+					furKey = parts[1]
+				case 3:
+					furSubsection = parts[1]
+					furKey = parts[2]
+				default:
+					t.Fatalf("unexpected split(%q): %v", gitKey, parts)
+				}
+
+				furValue := lookupValue(furConfig, furSection, furSubsection, furKey)
+				if gitValue != furValue {
+					t.Fatalf(
+						"key: %v (%v.%v.%v)\ngit: %q\nfur: %q",
+						gitKey, furSection, furSubsection, furKey, gitValue, furValue,
+					)
+				}
 			}
 		}
 	})
--