224 lines
5.6 KiB
Go
224 lines
5.6 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/steveyegge/beads/internal/types"
|
|
)
|
|
|
|
// TestImportMultiPartIDs tests that issue IDs with hyphens in the suffix
|
|
// (like "vc-baseline-test") are correctly recognized as having prefix "vc"
|
|
// and not treated as having different prefixes like "vc-baseline-"
|
|
func TestImportMultiPartIDs(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
dbPath := filepath.Join(tmpDir, ".beads", "beads.db")
|
|
|
|
// Create database with "vc" prefix
|
|
st := newTestStoreWithPrefix(t, dbPath, "vc")
|
|
|
|
ctx := context.Background()
|
|
|
|
// Create issues with multi-part IDs
|
|
issues := []*types.Issue{
|
|
{
|
|
ID: "vc-baseline-test",
|
|
Title: "Baseline test issue",
|
|
Description: "Issue with hyphenated suffix",
|
|
Status: "open",
|
|
Priority: 1,
|
|
IssueType: "task",
|
|
},
|
|
{
|
|
ID: "vc-92cl-gate-test",
|
|
Title: "Gate test issue",
|
|
Description: "Another issue with hyphenated suffix",
|
|
Status: "open",
|
|
Priority: 1,
|
|
IssueType: "task",
|
|
},
|
|
{
|
|
ID: "vc-test",
|
|
Title: "Simple test issue",
|
|
Description: "Issue without hyphenated suffix",
|
|
Status: "open",
|
|
Priority: 1,
|
|
IssueType: "task",
|
|
},
|
|
}
|
|
|
|
// Import should succeed without prefix mismatch errors
|
|
opts := ImportOptions{
|
|
DryRun: false,
|
|
SkipUpdate: false,
|
|
Strict: false,
|
|
}
|
|
|
|
result, err := importIssuesCore(ctx, dbPath, st, issues, opts)
|
|
if err != nil {
|
|
t.Fatalf("Import failed: %v", err)
|
|
}
|
|
|
|
// Should not detect prefix mismatch
|
|
if result.PrefixMismatch {
|
|
t.Errorf("Import incorrectly detected prefix mismatch")
|
|
t.Logf("Mismatched prefixes: %v", result.MismatchPrefixes)
|
|
}
|
|
|
|
// All issues should be created
|
|
if result.Created != 3 {
|
|
t.Errorf("Expected 3 issues created, got %d", result.Created)
|
|
}
|
|
|
|
// Verify issues exist in database
|
|
for _, issue := range issues {
|
|
dbIssue, err := st.GetIssue(ctx, issue.ID)
|
|
if err != nil {
|
|
t.Errorf("Failed to get issue %s: %v", issue.ID, err)
|
|
continue
|
|
}
|
|
if dbIssue.Title != issue.Title {
|
|
t.Errorf("Issue %s title mismatch: got %q, want %q", issue.ID, dbIssue.Title, issue.Title)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestImportMultiHyphenPrefix tests GH#422: importing with multi-hyphen prefixes
|
|
// like "asianops-audit-" should not cause false positive prefix mismatch errors.
|
|
func TestImportMultiHyphenPrefix(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
dbPath := filepath.Join(tmpDir, ".beads", "beads.db")
|
|
|
|
// Create database with multi-hyphen prefix "asianops-audit"
|
|
st := newTestStoreWithPrefix(t, dbPath, "asianops-audit")
|
|
|
|
ctx := context.Background()
|
|
|
|
// Create issues with hash-like suffixes that could be mistaken for words
|
|
// The key is that "test", "task", "demo" look like English words (4+ chars, no digits)
|
|
// which previously caused ExtractIssuePrefix to fall back to first hyphen
|
|
issues := []*types.Issue{
|
|
{
|
|
ID: "asianops-audit-sa0",
|
|
Title: "Issue with short hash suffix",
|
|
Description: "Short hash suffix should work",
|
|
Status: "open",
|
|
Priority: 1,
|
|
IssueType: "task",
|
|
},
|
|
{
|
|
ID: "asianops-audit-test",
|
|
Title: "Issue with word-like suffix",
|
|
Description: "Word-like suffix 'test' was causing false positive",
|
|
Status: "open",
|
|
Priority: 1,
|
|
IssueType: "task",
|
|
},
|
|
{
|
|
ID: "asianops-audit-task",
|
|
Title: "Another word-like suffix",
|
|
Description: "Word-like suffix 'task' was also problematic",
|
|
Status: "open",
|
|
Priority: 1,
|
|
IssueType: "task",
|
|
},
|
|
{
|
|
ID: "asianops-audit-demo",
|
|
Title: "Demo issue",
|
|
Description: "Word-like suffix 'demo'",
|
|
Status: "open",
|
|
Priority: 1,
|
|
IssueType: "task",
|
|
},
|
|
}
|
|
|
|
// Import should succeed without prefix mismatch errors
|
|
opts := ImportOptions{
|
|
DryRun: false,
|
|
SkipUpdate: false,
|
|
Strict: false,
|
|
}
|
|
|
|
result, err := importIssuesCore(ctx, dbPath, st, issues, opts)
|
|
if err != nil {
|
|
t.Fatalf("Import failed: %v", err)
|
|
}
|
|
|
|
// GH#422: Should NOT detect prefix mismatch
|
|
if result.PrefixMismatch {
|
|
t.Errorf("Import incorrectly detected prefix mismatch for multi-hyphen prefix")
|
|
t.Logf("Expected prefix: asianops-audit")
|
|
t.Logf("Mismatched prefixes detected: %v", result.MismatchPrefixes)
|
|
}
|
|
|
|
// All issues should be created
|
|
if result.Created != 4 {
|
|
t.Errorf("Expected 4 issues created, got %d", result.Created)
|
|
}
|
|
|
|
// Verify issues exist in database
|
|
for _, issue := range issues {
|
|
dbIssue, err := st.GetIssue(ctx, issue.ID)
|
|
if err != nil {
|
|
t.Errorf("Failed to get issue %s: %v", issue.ID, err)
|
|
continue
|
|
}
|
|
if dbIssue.Title != issue.Title {
|
|
t.Errorf("Issue %s title mismatch: got %q, want %q", issue.ID, dbIssue.Title, issue.Title)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestDetectPrefixFromIssues tests the detectPrefixFromIssues function
|
|
// with multi-part IDs
|
|
func TestDetectPrefixFromIssues(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
issues []*types.Issue
|
|
expected string
|
|
}{
|
|
{
|
|
name: "simple IDs",
|
|
issues: []*types.Issue{
|
|
{ID: "bd-1"},
|
|
{ID: "bd-2"},
|
|
{ID: "bd-3"},
|
|
},
|
|
expected: "bd",
|
|
},
|
|
{
|
|
name: "multi-part IDs",
|
|
issues: []*types.Issue{
|
|
{ID: "vc-baseline-test"},
|
|
{ID: "vc-92cl-gate-test"},
|
|
{ID: "vc-test"},
|
|
},
|
|
expected: "vc",
|
|
},
|
|
{
|
|
name: "mixed multi-part IDs",
|
|
issues: []*types.Issue{
|
|
{ID: "prefix-a-b-c"},
|
|
{ID: "prefix-x-y-z"},
|
|
{ID: "prefix-simple"},
|
|
},
|
|
expected: "prefix",
|
|
},
|
|
{
|
|
name: "empty list",
|
|
issues: []*types.Issue{},
|
|
expected: "",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := detectPrefixFromIssues(tt.issues)
|
|
if result != tt.expected {
|
|
t.Errorf("detectPrefixFromIssues() = %q, want %q", result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|