fix: respect hierarchy.max-depth config setting (GH#995) (#997)
* fix: respect hierarchy.max-depth config setting (GH#995) The hierarchy.max-depth config setting was being ignored because storage implementations had the depth limit hardcoded to 3. This fix: - Registers hierarchy.max-depth default (3) in config initialization - Adds hierarchy.max-depth to yaml-only keys for config.yaml storage - Updates SQLite and Memory storage to read max depth from config - Adds validation to reject hierarchy.max-depth values < 1 - Adds tests for configurable hierarchy depth Users can now set deeper hierarchies: bd config set hierarchy.max-depth 10 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: extract shared CheckHierarchyDepth function (GH#995) - Extract duplicated depth-checking logic to types.CheckHierarchyDepth() - Update sqlite and memory storage backends to use shared function - Add t.Cleanup() for proper test isolation in sqlite test - Add equivalent test coverage for memory storage backend - Add comprehensive unit tests for CheckHierarchyDepth function Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,10 @@ func TestIsYamlOnlyKey(t *testing.T) {
|
||||
{"daemon.auto_pull", true},
|
||||
{"daemon.custom_setting", true}, // prefix match
|
||||
|
||||
// Hierarchy settings (GH#995)
|
||||
{"hierarchy.max-depth", true},
|
||||
{"hierarchy.custom_setting", true}, // prefix match
|
||||
|
||||
// SQLite keys (should return false)
|
||||
{"jira.url", false},
|
||||
{"jira.project", false},
|
||||
@@ -164,10 +168,10 @@ func TestNormalizeYamlKey(t *testing.T) {
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{"sync.branch", "sync-branch"}, // alias should be normalized
|
||||
{"sync-branch", "sync-branch"}, // already canonical
|
||||
{"no-db", "no-db"}, // no alias, unchanged
|
||||
{"json", "json"}, // no alias, unchanged
|
||||
{"sync.branch", "sync-branch"}, // alias should be normalized
|
||||
{"sync-branch", "sync-branch"}, // already canonical
|
||||
{"no-db", "no-db"}, // no alias, unchanged
|
||||
{"json", "json"}, // no alias, unchanged
|
||||
{"routing.mode", "routing.mode"}, // no alias for this one
|
||||
}
|
||||
|
||||
@@ -328,3 +332,53 @@ other-setting: value
|
||||
t.Errorf("config.yaml should preserve other settings, got:\n%s", contentStr)
|
||||
}
|
||||
}
|
||||
|
||||
// TestValidateYamlConfigValue_HierarchyMaxDepth tests validation of hierarchy.max-depth (GH#995)
|
||||
func TestValidateYamlConfigValue_HierarchyMaxDepth(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
value string
|
||||
expectErr bool
|
||||
errMsg string
|
||||
}{
|
||||
{"valid positive integer", "5", false, ""},
|
||||
{"valid minimum value", "1", false, ""},
|
||||
{"valid large value", "100", false, ""},
|
||||
{"invalid zero", "0", true, "hierarchy.max-depth must be at least 1, got 0"},
|
||||
{"invalid negative", "-1", true, "hierarchy.max-depth must be at least 1, got -1"},
|
||||
{"invalid non-integer", "abc", true, "hierarchy.max-depth must be a positive integer, got \"abc\""},
|
||||
{"invalid float", "3.5", true, "hierarchy.max-depth must be a positive integer, got \"3.5\""},
|
||||
{"invalid empty", "", true, "hierarchy.max-depth must be a positive integer, got \"\""},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := validateYamlConfigValue("hierarchy.max-depth", tt.value)
|
||||
if tt.expectErr {
|
||||
if err == nil {
|
||||
t.Errorf("expected error for value %q, got nil", tt.value)
|
||||
} else if err.Error() != tt.errMsg {
|
||||
t.Errorf("expected error %q, got %q", tt.errMsg, err.Error())
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error for value %q: %v", tt.value, err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestValidateYamlConfigValue_OtherKeys tests that other keys are not validated
|
||||
func TestValidateYamlConfigValue_OtherKeys(t *testing.T) {
|
||||
// Other keys should pass validation regardless of value
|
||||
err := validateYamlConfigValue("no-db", "invalid")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error for no-db: %v", err)
|
||||
}
|
||||
|
||||
err = validateYamlConfigValue("routing.mode", "anything")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error for routing.mode: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user