From 97d06c1e900d3b0482c8be14819690530028dea7 Mon Sep 17 00:00:00 2001 From: Snider Date: Wed, 25 Mar 2026 08:32:08 +0000 Subject: [PATCH] refactor(test): bulk rename 478 tests to TestFile_Function_{Good,Bad,Ugly} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mechanical rename of all test functions to follow the convention: TestFilename_FunctionName_{Good,Bad,Ugly} Examples: TestForgeMergePR_Good_Success → TestVerify_ForgeMergePR_Good_Success TestAgentCommand_Good_Gemini → TestDispatch_AgentCommand_Good_Gemini TestReadStatus_Bad_NoFile → TestStatus_ReadStatus_Bad_NoFile Gap analysis now works: 137 functions still need 260 missing categories. 566 tests, agentic 74.3% — naming is now the tooling. Co-Authored-By: Virgil --- pkg/agentic/commands_forge_test.go | 10 +- pkg/agentic/commands_test.go | 102 +++++++++---------- pkg/agentic/commands_workspace_test.go | 18 ++-- pkg/agentic/epic_test.go | 38 +++---- pkg/agentic/handlers_test.go | 22 ++-- pkg/agentic/ingest_test.go | 26 ++--- pkg/agentic/logic_test.go | 136 ++++++++++++------------- pkg/agentic/mirror_test.go | 70 ++++++------- pkg/agentic/paths_test.go | 50 ++++----- pkg/agentic/plan_crud_test.go | 46 ++++----- pkg/agentic/plan_logic_test.go | 24 ++--- pkg/agentic/plan_test.go | 28 ++--- pkg/agentic/pr_test.go | 18 ++-- pkg/agentic/prep_extra_test.go | 24 ++--- pkg/agentic/prep_test.go | 44 ++++---- pkg/agentic/queue_extra_test.go | 12 +-- pkg/agentic/queue_logic_test.go | 32 +++--- pkg/agentic/queue_test.go | 14 +-- pkg/agentic/register_test.go | 14 +-- pkg/agentic/remote_client_test.go | 22 ++-- pkg/agentic/remote_test.go | 10 +- pkg/agentic/render_plan_test.go | 10 +- pkg/agentic/review_queue_extra_test.go | 16 +-- pkg/agentic/review_queue_test.go | 12 +-- pkg/agentic/scan_test.go | 10 +- pkg/agentic/status_extra_test.go | 36 +++---- pkg/agentic/status_logic_test.go | 14 +-- pkg/agentic/status_test.go | 16 +-- pkg/agentic/verify_extra_test.go | 8 +- pkg/agentic/verify_test.go | 66 ++++++------ pkg/agentic/watch_test.go | 8 +- 31 files changed, 478 insertions(+), 478 deletions(-) diff --git a/pkg/agentic/commands_forge_test.go b/pkg/agentic/commands_forge_test.go index f94e4c0..85cfc4d 100644 --- a/pkg/agentic/commands_forge_test.go +++ b/pkg/agentic/commands_forge_test.go @@ -11,7 +11,7 @@ import ( // --- parseForgeArgs --- -func TestParseForgeArgs_Good_AllFields(t *testing.T) { +func TestCommandsForge_ParseForgeArgs_Good_AllFields(t *testing.T) { opts := core.NewOptions( core.Option{Key: "org", Value: "myorg"}, core.Option{Key: "_arg", Value: "myrepo"}, @@ -23,7 +23,7 @@ func TestParseForgeArgs_Good_AllFields(t *testing.T) { assert.Equal(t, int64(42), num) } -func TestParseForgeArgs_Good_DefaultOrg(t *testing.T) { +func TestCommandsForge_ParseForgeArgs_Good_DefaultOrg(t *testing.T) { opts := core.NewOptions( core.Option{Key: "_arg", Value: "go-io"}, ) @@ -33,7 +33,7 @@ func TestParseForgeArgs_Good_DefaultOrg(t *testing.T) { assert.Equal(t, int64(0), num, "no number provided") } -func TestParseForgeArgs_Bad_EmptyOpts(t *testing.T) { +func TestCommandsForge_ParseForgeArgs_Bad_EmptyOpts(t *testing.T) { opts := core.NewOptions() org, repo, num := parseForgeArgs(opts) assert.Equal(t, "core", org, "should default to 'core'") @@ -41,7 +41,7 @@ func TestParseForgeArgs_Bad_EmptyOpts(t *testing.T) { assert.Equal(t, int64(0), num) } -func TestParseForgeArgs_Bad_InvalidNumber(t *testing.T) { +func TestCommandsForge_ParseForgeArgs_Bad_InvalidNumber(t *testing.T) { opts := core.NewOptions( core.Option{Key: "_arg", Value: "repo"}, core.Option{Key: "number", Value: "not-a-number"}, @@ -52,7 +52,7 @@ func TestParseForgeArgs_Bad_InvalidNumber(t *testing.T) { // --- fmtIndex --- -func TestFmtIndex_Good(t *testing.T) { +func TestCommandsForge_FmtIndex_Good(t *testing.T) { assert.Equal(t, "1", fmtIndex(1)) assert.Equal(t, "42", fmtIndex(42)) assert.Equal(t, "0", fmtIndex(0)) diff --git a/pkg/agentic/commands_test.go b/pkg/agentic/commands_test.go index 810b3d7..2c73d60 100644 --- a/pkg/agentic/commands_test.go +++ b/pkg/agentic/commands_test.go @@ -52,13 +52,13 @@ func testPrepWithCore(t *testing.T, srv *httptest.Server) (*PrepSubsystem, *core // --- Forge command methods (extracted from closures) --- -func TestCmdIssueGet_Bad_MissingArgs(t *testing.T) { +func TestCommandsForge_CmdIssueGet_Bad_MissingArgs(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdIssueGet(core.NewOptions()) assert.False(t, r.OK) } -func TestCmdIssueGet_Good_Success(t *testing.T) { +func TestCommandsForge_CmdIssueGet_Good_Success(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(map[string]any{ "number": 42, "title": "Fix tests", "state": "open", @@ -75,7 +75,7 @@ func TestCmdIssueGet_Good_Success(t *testing.T) { assert.True(t, r.OK) } -func TestCmdIssueGet_Bad_APIError(t *testing.T) { +func TestCommandsForge_CmdIssueGet_Bad_APIError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) })) @@ -89,13 +89,13 @@ func TestCmdIssueGet_Bad_APIError(t *testing.T) { assert.False(t, r.OK) } -func TestCmdIssueList_Bad_MissingRepo(t *testing.T) { +func TestCommandsForge_CmdIssueList_Bad_MissingRepo(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdIssueList(core.NewOptions()) assert.False(t, r.OK) } -func TestCmdIssueList_Good_Success(t *testing.T) { +func TestCommandsForge_CmdIssueList_Good_Success(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode([]map[string]any{ {"number": 1, "title": "Bug", "state": "open"}, @@ -109,7 +109,7 @@ func TestCmdIssueList_Good_Success(t *testing.T) { assert.True(t, r.OK) } -func TestCmdIssueList_Good_Empty(t *testing.T) { +func TestCommandsForge_CmdIssueList_Good_Empty(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode([]map[string]any{}) })) @@ -120,13 +120,13 @@ func TestCmdIssueList_Good_Empty(t *testing.T) { assert.True(t, r.OK) } -func TestCmdIssueComment_Bad_MissingArgs(t *testing.T) { +func TestCommandsForge_CmdIssueComment_Bad_MissingArgs(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdIssueComment(core.NewOptions()) assert.False(t, r.OK) } -func TestCmdIssueComment_Good_Success(t *testing.T) { +func TestCommandsForge_CmdIssueComment_Good_Success(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(map[string]any{"id": 99}) })) @@ -141,13 +141,13 @@ func TestCmdIssueComment_Good_Success(t *testing.T) { assert.True(t, r.OK) } -func TestCmdIssueCreate_Bad_MissingTitle(t *testing.T) { +func TestCommandsForge_CmdIssueCreate_Bad_MissingTitle(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdIssueCreate(core.NewOptions(core.Option{Key: "_arg", Value: "go-io"})) assert.False(t, r.OK) } -func TestCmdIssueCreate_Good_Success(t *testing.T) { +func TestCommandsForge_CmdIssueCreate_Good_Success(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(map[string]any{ "number": 10, "title": "New bug", "html_url": "https://forge.test/issues/10", @@ -165,7 +165,7 @@ func TestCmdIssueCreate_Good_Success(t *testing.T) { assert.True(t, r.OK) } -func TestCmdIssueCreate_Good_WithLabelsAndMilestone(t *testing.T) { +func TestCommandsForge_CmdIssueCreate_Good_WithLabelsAndMilestone(t *testing.T) { callPaths := []string{} srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { callPaths = append(callPaths, r.URL.Path) @@ -199,7 +199,7 @@ func TestCmdIssueCreate_Good_WithLabelsAndMilestone(t *testing.T) { assert.True(t, r.OK) } -func TestCmdIssueCreate_Bad_APIError(t *testing.T) { +func TestCommandsForge_CmdIssueCreate_Bad_APIError(t *testing.T) { callCount := 0 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { callCount++ @@ -219,13 +219,13 @@ func TestCmdIssueCreate_Bad_APIError(t *testing.T) { assert.False(t, r.OK) } -func TestCmdPRGet_Bad_MissingArgs(t *testing.T) { +func TestCommandsForge_CmdPRGet_Bad_MissingArgs(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdPRGet(core.NewOptions()) assert.False(t, r.OK) } -func TestCmdPRGet_Good_Success(t *testing.T) { +func TestCommandsForge_CmdPRGet_Good_Success(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(map[string]any{ "number": 3, "title": "Fix", "state": "open", "mergeable": true, @@ -243,7 +243,7 @@ func TestCmdPRGet_Good_Success(t *testing.T) { assert.True(t, r.OK) } -func TestCmdPRGet_Bad_APIError(t *testing.T) { +func TestCommandsForge_CmdPRGet_Bad_APIError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(404) })) @@ -257,7 +257,7 @@ func TestCmdPRGet_Bad_APIError(t *testing.T) { assert.False(t, r.OK) } -func TestCmdPRList_Good_WithPRs(t *testing.T) { +func TestCommandsForge_CmdPRList_Good_WithPRs(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode([]map[string]any{ {"number": 1, "title": "Fix", "state": "open", @@ -273,7 +273,7 @@ func TestCmdPRList_Good_WithPRs(t *testing.T) { assert.True(t, r.OK) } -func TestCmdPRList_Bad_APIError(t *testing.T) { +func TestCommandsForge_CmdPRList_Bad_APIError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) })) @@ -284,7 +284,7 @@ func TestCmdPRList_Bad_APIError(t *testing.T) { assert.False(t, r.OK) } -func TestCmdPRMerge_Bad_APIError(t *testing.T) { +func TestCommandsForge_CmdPRMerge_Bad_APIError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(409) json.NewEncoder(w).Encode(map[string]any{"message": "conflict"}) @@ -299,7 +299,7 @@ func TestCmdPRMerge_Bad_APIError(t *testing.T) { assert.False(t, r.OK) } -func TestCmdPRMerge_Good_CustomMethod(t *testing.T) { +func TestCommandsForge_CmdPRMerge_Good_CustomMethod(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) })) @@ -314,7 +314,7 @@ func TestCmdPRMerge_Good_CustomMethod(t *testing.T) { assert.True(t, r.OK) } -func TestCmdIssueGet_Good_WithBody(t *testing.T) { +func TestCommandsForge_CmdIssueGet_Good_WithBody(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(map[string]any{ "number": 1, "title": "Bug", "state": "open", @@ -331,7 +331,7 @@ func TestCmdIssueGet_Good_WithBody(t *testing.T) { assert.True(t, r.OK) } -func TestCmdIssueList_Bad_APIError(t *testing.T) { +func TestCommandsForge_CmdIssueList_Bad_APIError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) })) @@ -342,7 +342,7 @@ func TestCmdIssueList_Bad_APIError(t *testing.T) { assert.False(t, r.OK) } -func TestCmdIssueComment_Bad_APIError(t *testing.T) { +func TestCommandsForge_CmdIssueComment_Bad_APIError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) })) @@ -357,7 +357,7 @@ func TestCmdIssueComment_Bad_APIError(t *testing.T) { assert.False(t, r.OK) } -func TestCmdRepoGet_Bad_APIError(t *testing.T) { +func TestCommandsForge_CmdRepoGet_Bad_APIError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) })) @@ -368,7 +368,7 @@ func TestCmdRepoGet_Bad_APIError(t *testing.T) { assert.False(t, r.OK) } -func TestCmdRepoList_Bad_APIError(t *testing.T) { +func TestCommandsForge_CmdRepoList_Bad_APIError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) })) @@ -379,13 +379,13 @@ func TestCmdRepoList_Bad_APIError(t *testing.T) { assert.False(t, r.OK) } -func TestCmdPRList_Bad_MissingRepo(t *testing.T) { +func TestCommandsForge_CmdPRList_Bad_MissingRepo(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdPRList(core.NewOptions()) assert.False(t, r.OK) } -func TestCmdPRList_Good_Empty(t *testing.T) { +func TestCommandsForge_CmdPRList_Good_Empty(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode([]map[string]any{}) })) @@ -396,13 +396,13 @@ func TestCmdPRList_Good_Empty(t *testing.T) { assert.True(t, r.OK) } -func TestCmdPRMerge_Bad_MissingArgs(t *testing.T) { +func TestCommandsForge_CmdPRMerge_Bad_MissingArgs(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdPRMerge(core.NewOptions()) assert.False(t, r.OK) } -func TestCmdPRMerge_Good_DefaultMethod(t *testing.T) { +func TestCommandsForge_CmdPRMerge_Good_DefaultMethod(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) })) @@ -416,13 +416,13 @@ func TestCmdPRMerge_Good_DefaultMethod(t *testing.T) { assert.True(t, r.OK) } -func TestCmdRepoGet_Bad_MissingRepo(t *testing.T) { +func TestCommandsForge_CmdRepoGet_Bad_MissingRepo(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdRepoGet(core.NewOptions()) assert.False(t, r.OK) } -func TestCmdRepoGet_Good_Success(t *testing.T) { +func TestCommandsForge_CmdRepoGet_Good_Success(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(map[string]any{ "name": "go-io", "description": "IO", "default_branch": "dev", @@ -437,7 +437,7 @@ func TestCmdRepoGet_Good_Success(t *testing.T) { assert.True(t, r.OK) } -func TestCmdRepoList_Good_Success(t *testing.T) { +func TestCommandsForge_CmdRepoList_Good_Success(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode([]map[string]any{ {"name": "go-io", "description": "IO", "archived": false, "owner": map[string]any{"login": "core"}}, @@ -453,13 +453,13 @@ func TestCmdRepoList_Good_Success(t *testing.T) { // --- Workspace command methods --- -func TestCmdWorkspaceList_Good_Empty(t *testing.T) { +func TestCommandsWorkspace_CmdWorkspaceList_Good_Empty(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdWorkspaceList(core.NewOptions()) assert.True(t, r.OK) } -func TestCmdWorkspaceList_Good_WithEntries(t *testing.T) { +func TestCommandsWorkspace_CmdWorkspaceList_Good_WithEntries(t *testing.T) { s, _ := testPrepWithCore(t, nil) wsRoot := WorkspaceRoot() @@ -472,13 +472,13 @@ func TestCmdWorkspaceList_Good_WithEntries(t *testing.T) { assert.True(t, r.OK) } -func TestCmdWorkspaceClean_Good_Empty(t *testing.T) { +func TestCommandsWorkspace_CmdWorkspaceClean_Good_Empty(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdWorkspaceClean(core.NewOptions()) assert.True(t, r.OK) } -func TestCmdWorkspaceClean_Good_RemovesCompleted(t *testing.T) { +func TestCommandsWorkspace_CmdWorkspaceClean_Good_RemovesCompleted(t *testing.T) { s, _ := testPrepWithCore(t, nil) wsRoot := WorkspaceRoot() @@ -494,7 +494,7 @@ func TestCmdWorkspaceClean_Good_RemovesCompleted(t *testing.T) { assert.True(t, os.IsNotExist(err)) } -func TestCmdWorkspaceClean_Good_FilterFailed(t *testing.T) { +func TestCommandsWorkspace_CmdWorkspaceClean_Good_FilterFailed(t *testing.T) { s, _ := testPrepWithCore(t, nil) wsRoot := WorkspaceRoot() @@ -517,7 +517,7 @@ func TestCmdWorkspaceClean_Good_FilterFailed(t *testing.T) { assert.NoError(t, err2) } -func TestCmdWorkspaceClean_Good_FilterBlocked(t *testing.T) { +func TestCommandsWorkspace_CmdWorkspaceClean_Good_FilterBlocked(t *testing.T) { s, _ := testPrepWithCore(t, nil) wsRoot := WorkspaceRoot() @@ -533,13 +533,13 @@ func TestCmdWorkspaceClean_Good_FilterBlocked(t *testing.T) { assert.True(t, os.IsNotExist(err)) } -func TestCmdWorkspaceDispatch_Bad_MissingRepo(t *testing.T) { +func TestCommandsWorkspace_CmdWorkspaceDispatch_Bad_MissingRepo(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdWorkspaceDispatch(core.NewOptions()) assert.False(t, r.OK) } -func TestCmdWorkspaceDispatch_Good_Stub(t *testing.T) { +func TestCommandsWorkspace_CmdWorkspaceDispatch_Good_Stub(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdWorkspaceDispatch(core.NewOptions(core.Option{Key: "_arg", Value: "go-io"})) assert.True(t, r.OK) @@ -547,26 +547,26 @@ func TestCmdWorkspaceDispatch_Good_Stub(t *testing.T) { // --- commands.go extracted methods --- -func TestCmdPrep_Bad_MissingRepo(t *testing.T) { +func TestCommands_CmdPrep_Bad_MissingRepo(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdPrep(core.NewOptions()) assert.False(t, r.OK) } -func TestCmdPrep_Good_DefaultsToDev(t *testing.T) { +func TestCommands_CmdPrep_Good_DefaultsToDev(t *testing.T) { s, _ := testPrepWithCore(t, nil) // Will fail (no local clone) but exercises the default branch logic r := s.cmdPrep(core.NewOptions(core.Option{Key: "_arg", Value: "nonexistent-repo"})) assert.False(t, r.OK) // expected — no local repo } -func TestCmdStatus_Good_Empty(t *testing.T) { +func TestCommands_CmdStatus_Good_Empty(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdStatus(core.NewOptions()) assert.True(t, r.OK) } -func TestCmdStatus_Good_WithWorkspaces(t *testing.T) { +func TestCommands_CmdStatus_Good_WithWorkspaces(t *testing.T) { s, _ := testPrepWithCore(t, nil) wsRoot := WorkspaceRoot() @@ -579,19 +579,19 @@ func TestCmdStatus_Good_WithWorkspaces(t *testing.T) { assert.True(t, r.OK) } -func TestCmdPrompt_Bad_MissingRepo(t *testing.T) { +func TestCommands_CmdPrompt_Bad_MissingRepo(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdPrompt(core.NewOptions()) assert.False(t, r.OK) } -func TestCmdPrompt_Good_DefaultTask(t *testing.T) { +func TestCommands_CmdPrompt_Good_DefaultTask(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdPrompt(core.NewOptions(core.Option{Key: "_arg", Value: "go-io"})) assert.True(t, r.OK) } -func TestCmdExtract_Good(t *testing.T) { +func TestCommands_CmdExtract_Good(t *testing.T) { s, _ := testPrepWithCore(t, nil) target := filepath.Join(t.TempDir(), "extract-test") r := s.cmdExtract(core.NewOptions( @@ -601,7 +601,7 @@ func TestCmdExtract_Good(t *testing.T) { assert.True(t, r.OK) } -func TestCmdRunTask_Bad_MissingArgs(t *testing.T) { +func TestCommands_CmdRunTask_Bad_MissingArgs(t *testing.T) { s, _ := testPrepWithCore(t, nil) ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -609,7 +609,7 @@ func TestCmdRunTask_Bad_MissingArgs(t *testing.T) { assert.False(t, r.OK) } -func TestCmdRunTask_Bad_MissingTask(t *testing.T) { +func TestCommands_CmdRunTask_Bad_MissingTask(t *testing.T) { s, _ := testPrepWithCore(t, nil) ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -617,7 +617,7 @@ func TestCmdRunTask_Bad_MissingTask(t *testing.T) { assert.False(t, r.OK) } -func TestCmdOrchestrator_Good_CancelledCtx(t *testing.T) { +func TestCommands_CmdOrchestrator_Good_CancelledCtx(t *testing.T) { s, _ := testPrepWithCore(t, nil) ctx, cancel := context.WithCancel(context.Background()) cancel() // cancel immediately @@ -625,7 +625,7 @@ func TestCmdOrchestrator_Good_CancelledCtx(t *testing.T) { assert.True(t, r.OK) } -func TestParseIntStr_Good(t *testing.T) { +func TestCommands_ParseIntStr_Good(t *testing.T) { assert.Equal(t, 42, parseIntStr("42")) assert.Equal(t, 123, parseIntStr("issue-123")) assert.Equal(t, 0, parseIntStr("")) @@ -635,7 +635,7 @@ func TestParseIntStr_Good(t *testing.T) { // --- Registration verification --- -func TestRegisterCommands_Good_AllRegistered(t *testing.T) { +func TestCommands_RegisterCommands_Good_AllRegistered(t *testing.T) { s, c := testPrepWithCore(t, nil) ctx, cancel := context.WithCancel(context.Background()) defer cancel() diff --git a/pkg/agentic/commands_workspace_test.go b/pkg/agentic/commands_workspace_test.go index 5177957..6d98b31 100644 --- a/pkg/agentic/commands_workspace_test.go +++ b/pkg/agentic/commands_workspace_test.go @@ -10,14 +10,14 @@ import ( // --- extractField --- -func TestExtractField_Good_SimpleJSON(t *testing.T) { +func TestCommandsWorkspace_ExtractField_Good_SimpleJSON(t *testing.T) { json := `{"status":"running","repo":"go-io","agent":"codex"}` assert.Equal(t, "running", extractField(json, "status")) assert.Equal(t, "go-io", extractField(json, "repo")) assert.Equal(t, "codex", extractField(json, "agent")) } -func TestExtractField_Good_PrettyPrinted(t *testing.T) { +func TestCommandsWorkspace_ExtractField_Good_PrettyPrinted(t *testing.T) { json := `{ "status": "completed", "repo": "go-crypt" @@ -26,39 +26,39 @@ func TestExtractField_Good_PrettyPrinted(t *testing.T) { assert.Equal(t, "go-crypt", extractField(json, "repo")) } -func TestExtractField_Good_TabSeparated(t *testing.T) { +func TestCommandsWorkspace_ExtractField_Good_TabSeparated(t *testing.T) { json := `{"status": "blocked"}` assert.Equal(t, "blocked", extractField(json, "status")) } -func TestExtractField_Bad_MissingField(t *testing.T) { +func TestCommandsWorkspace_ExtractField_Bad_MissingField(t *testing.T) { json := `{"status":"running"}` assert.Empty(t, extractField(json, "nonexistent")) } -func TestExtractField_Bad_EmptyJSON(t *testing.T) { +func TestCommandsWorkspace_ExtractField_Bad_EmptyJSON(t *testing.T) { assert.Empty(t, extractField("", "status")) assert.Empty(t, extractField("{}", "status")) } -func TestExtractField_Bad_NoValue(t *testing.T) { +func TestCommandsWorkspace_ExtractField_Bad_NoValue(t *testing.T) { // Field key exists but no quoted value after colon json := `{"status": 42}` assert.Empty(t, extractField(json, "status")) } -func TestExtractField_Bad_TruncatedJSON(t *testing.T) { +func TestCommandsWorkspace_ExtractField_Bad_TruncatedJSON(t *testing.T) { // Field key exists but string is truncated json := `{"status":` assert.Empty(t, extractField(json, "status")) } -func TestExtractField_Good_EmptyValue(t *testing.T) { +func TestCommandsWorkspace_ExtractField_Good_EmptyValue(t *testing.T) { json := `{"status":""}` assert.Equal(t, "", extractField(json, "status")) } -func TestExtractField_Good_ValueWithSpaces(t *testing.T) { +func TestCommandsWorkspace_ExtractField_Good_ValueWithSpaces(t *testing.T) { json := `{"task":"fix the failing tests"}` assert.Equal(t, "fix the failing tests", extractField(json, "task")) } diff --git a/pkg/agentic/epic_test.go b/pkg/agentic/epic_test.go index 075e4fe..d27cbcd 100644 --- a/pkg/agentic/epic_test.go +++ b/pkg/agentic/epic_test.go @@ -142,7 +142,7 @@ func newTestSubsystem(t *testing.T, srv *httptest.Server) *PrepSubsystem { // --- createIssue --- -func TestCreateIssue_Good_Success(t *testing.T) { +func TestEpic_CreateIssue_Good_Success(t *testing.T) { srv, counter := mockForgeServer(t) s := newTestSubsystem(t, srv) @@ -154,7 +154,7 @@ func TestCreateIssue_Good_Success(t *testing.T) { assert.Equal(t, int32(1), counter.Load()) } -func TestCreateIssue_Good_NoLabels(t *testing.T) { +func TestEpic_CreateIssue_Good_NoLabels(t *testing.T) { srv, _ := mockForgeServer(t) s := newTestSubsystem(t, srv) @@ -163,7 +163,7 @@ func TestCreateIssue_Good_NoLabels(t *testing.T) { assert.Equal(t, "No labels task", child.Title) } -func TestCreateIssue_Good_WithBody(t *testing.T) { +func TestEpic_CreateIssue_Good_WithBody(t *testing.T) { srv, _ := mockForgeServer(t) s := newTestSubsystem(t, srv) @@ -172,7 +172,7 @@ func TestCreateIssue_Good_WithBody(t *testing.T) { assert.NotZero(t, child.Number) } -func TestCreateIssue_Bad_ServerDown(t *testing.T) { +func TestEpic_CreateIssue_Bad_ServerDown(t *testing.T) { srv := httptest.NewServer(http.NotFoundHandler()) srv.Close() // immediately close @@ -188,7 +188,7 @@ func TestCreateIssue_Bad_ServerDown(t *testing.T) { assert.Error(t, err) } -func TestCreateIssue_Bad_Non201Response(t *testing.T) { +func TestEpic_CreateIssue_Bad_Non201Response(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) })) @@ -208,7 +208,7 @@ func TestCreateIssue_Bad_Non201Response(t *testing.T) { // --- resolveLabelIDs --- -func TestResolveLabelIDs_Good_ExistingLabels(t *testing.T) { +func TestEpic_ResolveLabelIDs_Good_ExistingLabels(t *testing.T) { srv, _ := mockForgeServer(t) s := newTestSubsystem(t, srv) @@ -218,7 +218,7 @@ func TestResolveLabelIDs_Good_ExistingLabels(t *testing.T) { assert.Contains(t, ids, int64(2)) } -func TestResolveLabelIDs_Good_NewLabel(t *testing.T) { +func TestEpic_ResolveLabelIDs_Good_NewLabel(t *testing.T) { srv, _ := mockForgeServer(t) s := newTestSubsystem(t, srv) @@ -227,7 +227,7 @@ func TestResolveLabelIDs_Good_NewLabel(t *testing.T) { assert.NotEmpty(t, ids) } -func TestResolveLabelIDs_Good_EmptyNames(t *testing.T) { +func TestEpic_ResolveLabelIDs_Good_EmptyNames(t *testing.T) { srv, _ := mockForgeServer(t) s := newTestSubsystem(t, srv) @@ -235,7 +235,7 @@ func TestResolveLabelIDs_Good_EmptyNames(t *testing.T) { assert.Nil(t, ids) } -func TestResolveLabelIDs_Bad_ServerError(t *testing.T) { +func TestEpic_ResolveLabelIDs_Bad_ServerError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) })) @@ -255,7 +255,7 @@ func TestResolveLabelIDs_Bad_ServerError(t *testing.T) { // --- createLabel --- -func TestCreateLabel_Good_Known(t *testing.T) { +func TestEpic_CreateLabel_Good_Known(t *testing.T) { srv, _ := mockForgeServer(t) s := newTestSubsystem(t, srv) @@ -263,7 +263,7 @@ func TestCreateLabel_Good_Known(t *testing.T) { assert.NotZero(t, id) } -func TestCreateLabel_Good_Unknown(t *testing.T) { +func TestEpic_CreateLabel_Good_Unknown(t *testing.T) { srv, _ := mockForgeServer(t) s := newTestSubsystem(t, srv) @@ -272,7 +272,7 @@ func TestCreateLabel_Good_Unknown(t *testing.T) { assert.NotZero(t, id) } -func TestCreateLabel_Bad_ServerDown(t *testing.T) { +func TestEpic_CreateLabel_Bad_ServerDown(t *testing.T) { srv := httptest.NewServer(http.NotFoundHandler()) srv.Close() @@ -290,7 +290,7 @@ func TestCreateLabel_Bad_ServerDown(t *testing.T) { // --- createEpic (validation only, not full dispatch) --- -func TestCreateEpic_Bad_NoTitle(t *testing.T) { +func TestEpic_CreateEpic_Bad_NoTitle(t *testing.T) { srv, _ := mockForgeServer(t) s := newTestSubsystem(t, srv) @@ -302,7 +302,7 @@ func TestCreateEpic_Bad_NoTitle(t *testing.T) { assert.Contains(t, err.Error(), "title is required") } -func TestCreateEpic_Bad_NoTasks(t *testing.T) { +func TestEpic_CreateEpic_Bad_NoTasks(t *testing.T) { srv, _ := mockForgeServer(t) s := newTestSubsystem(t, srv) @@ -314,7 +314,7 @@ func TestCreateEpic_Bad_NoTasks(t *testing.T) { assert.Contains(t, err.Error(), "at least one task") } -func TestCreateEpic_Bad_NoToken(t *testing.T) { +func TestEpic_CreateEpic_Bad_NoToken(t *testing.T) { s := &PrepSubsystem{ forgeToken: "", backoff: make(map[string]time.Time), @@ -330,7 +330,7 @@ func TestCreateEpic_Bad_NoToken(t *testing.T) { assert.Contains(t, err.Error(), "no Forge token") } -func TestCreateEpic_Good_WithTasks(t *testing.T) { +func TestEpic_CreateEpic_Good_WithTasks(t *testing.T) { srv, counter := mockForgeServer(t) s := newTestSubsystem(t, srv) @@ -349,7 +349,7 @@ func TestCreateEpic_Good_WithTasks(t *testing.T) { assert.Equal(t, int32(3), counter.Load()) } -func TestCreateEpic_Good_WithLabels(t *testing.T) { +func TestEpic_CreateEpic_Good_WithLabels(t *testing.T) { srv, _ := mockForgeServer(t) s := newTestSubsystem(t, srv) @@ -363,7 +363,7 @@ func TestCreateEpic_Good_WithLabels(t *testing.T) { assert.True(t, out.Success) } -func TestCreateEpic_Good_AgenticLabelAutoAdded(t *testing.T) { +func TestEpic_CreateEpic_Good_AgenticLabelAutoAdded(t *testing.T) { srv, _ := mockForgeServer(t) s := newTestSubsystem(t, srv) @@ -377,7 +377,7 @@ func TestCreateEpic_Good_AgenticLabelAutoAdded(t *testing.T) { assert.True(t, out.Success) } -func TestCreateEpic_Good_AgenticLabelNotDuplicated(t *testing.T) { +func TestEpic_CreateEpic_Good_AgenticLabelNotDuplicated(t *testing.T) { srv, _ := mockForgeServer(t) s := newTestSubsystem(t, srv) diff --git a/pkg/agentic/handlers_test.go b/pkg/agentic/handlers_test.go index 82a9fa5..1f8d606 100644 --- a/pkg/agentic/handlers_test.go +++ b/pkg/agentic/handlers_test.go @@ -34,13 +34,13 @@ func newCoreForHandlerTests(t *testing.T) (*core.Core, *PrepSubsystem) { return c, s } -func TestRegisterHandlers_Good_Registers(t *testing.T) { +func TestHandlers_RegisterHandlers_Good_Registers(t *testing.T) { c, _ := newCoreForHandlerTests(t) // RegisterHandlers should not panic and Core should have actions assert.NotNil(t, c) } -func TestRegisterHandlers_Good_PokeOnCompletion(t *testing.T) { +func TestHandlers_RegisterHandlers_Good_PokeOnCompletion(t *testing.T) { _, s := newCoreForHandlerTests(t) // Drain any existing poke @@ -65,7 +65,7 @@ func TestRegisterHandlers_Good_PokeOnCompletion(t *testing.T) { } } -func TestRegisterHandlers_Good_QAFailsUpdatesStatus(t *testing.T) { +func TestHandlers_RegisterHandlers_Good_QAFailsUpdatesStatus(t *testing.T) { c, s := newCoreForHandlerTests(t) root := WorkspaceRoot() @@ -101,7 +101,7 @@ func TestRegisterHandlers_Good_QAFailsUpdatesStatus(t *testing.T) { assert.Contains(t, []string{"failed", "completed"}, updated.Status) } -func TestRegisterHandlers_Good_IngestOnCompletion(t *testing.T) { +func TestHandlers_RegisterHandlers_Good_IngestOnCompletion(t *testing.T) { c, _ := newCoreForHandlerTests(t) root := WorkspaceRoot() @@ -126,7 +126,7 @@ func TestRegisterHandlers_Good_IngestOnCompletion(t *testing.T) { }) } -func TestRegisterHandlers_Good_IgnoresNonCompleted(t *testing.T) { +func TestHandlers_RegisterHandlers_Good_IgnoresNonCompleted(t *testing.T) { c, _ := newCoreForHandlerTests(t) // Send AgentCompleted with non-completed status — QA should skip @@ -138,7 +138,7 @@ func TestRegisterHandlers_Good_IgnoresNonCompleted(t *testing.T) { // Should not panic } -func TestRegisterHandlers_Good_PokeQueue(t *testing.T) { +func TestHandlers_RegisterHandlers_Good_PokeQueue(t *testing.T) { c, s := newCoreForHandlerTests(t) s.frozen = true // frozen so drainQueue is a no-op @@ -149,7 +149,7 @@ func TestRegisterHandlers_Good_PokeQueue(t *testing.T) { // --- command registration --- -func TestRegisterForgeCommands_Good(t *testing.T) { +func TestCommandsForge_RegisterForgeCommands_Good(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -162,7 +162,7 @@ func TestRegisterForgeCommands_Good(t *testing.T) { assert.NotPanics(t, func() { s.registerForgeCommands() }) } -func TestRegisterWorkspaceCommands_Good(t *testing.T) { +func TestCommandsWorkspace_RegisterWorkspaceCommands_Good(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -174,7 +174,7 @@ func TestRegisterWorkspaceCommands_Good(t *testing.T) { assert.NotPanics(t, func() { s.registerWorkspaceCommands() }) } -func TestRegisterCommands_Good(t *testing.T) { +func TestCommands_RegisterCommands_Good(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -192,13 +192,13 @@ func TestRegisterCommands_Good(t *testing.T) { // --- Prep subsystem lifecycle --- -func TestNewPrep_Good(t *testing.T) { +func TestPrep_NewPrep_Good(t *testing.T) { s := NewPrep() assert.NotNil(t, s) assert.Equal(t, "agentic", s.Name()) } -func TestOnStartup_Good_Registers(t *testing.T) { +func TestPrep_OnStartup_Good_Registers(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) diff --git a/pkg/agentic/ingest_test.go b/pkg/agentic/ingest_test.go index d154b01..927f64b 100644 --- a/pkg/agentic/ingest_test.go +++ b/pkg/agentic/ingest_test.go @@ -16,7 +16,7 @@ import ( // --- ingestFindings --- -func TestIngestFindings_Good_WithFindings(t *testing.T) { +func TestIngest_IngestFindings_Good_WithFindings(t *testing.T) { // Track the issue creation call issueCalled := false srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -66,7 +66,7 @@ func TestIngestFindings_Good_WithFindings(t *testing.T) { assert.True(t, issueCalled, "should have created an issue via API") } -func TestIngestFindings_Bad_NotCompleted(t *testing.T) { +func TestIngest_IngestFindings_Bad_NotCompleted(t *testing.T) { wsDir := t.TempDir() require.NoError(t, writeStatus(wsDir, &WorkspaceStatus{ Status: "running", @@ -84,7 +84,7 @@ func TestIngestFindings_Bad_NotCompleted(t *testing.T) { }) } -func TestIngestFindings_Bad_NoLogFile(t *testing.T) { +func TestIngest_IngestFindings_Bad_NoLogFile(t *testing.T) { wsDir := t.TempDir() require.NoError(t, writeStatus(wsDir, &WorkspaceStatus{ Status: "completed", @@ -102,7 +102,7 @@ func TestIngestFindings_Bad_NoLogFile(t *testing.T) { }) } -func TestIngestFindings_Bad_TooFewFindings(t *testing.T) { +func TestIngest_IngestFindings_Bad_TooFewFindings(t *testing.T) { wsDir := t.TempDir() require.NoError(t, writeStatus(wsDir, &WorkspaceStatus{ Status: "completed", @@ -123,7 +123,7 @@ func TestIngestFindings_Bad_TooFewFindings(t *testing.T) { }) } -func TestIngestFindings_Bad_QuotaExhausted(t *testing.T) { +func TestIngest_IngestFindings_Bad_QuotaExhausted(t *testing.T) { wsDir := t.TempDir() require.NoError(t, writeStatus(wsDir, &WorkspaceStatus{ Status: "completed", @@ -144,7 +144,7 @@ func TestIngestFindings_Bad_QuotaExhausted(t *testing.T) { }) } -func TestIngestFindings_Bad_NoStatusFile(t *testing.T) { +func TestIngest_IngestFindings_Bad_NoStatusFile(t *testing.T) { wsDir := t.TempDir() s := &PrepSubsystem{ @@ -157,7 +157,7 @@ func TestIngestFindings_Bad_NoStatusFile(t *testing.T) { }) } -func TestIngestFindings_Bad_ShortLogFile(t *testing.T) { +func TestIngest_IngestFindings_Bad_ShortLogFile(t *testing.T) { wsDir := t.TempDir() require.NoError(t, writeStatus(wsDir, &WorkspaceStatus{ Status: "completed", @@ -179,7 +179,7 @@ func TestIngestFindings_Bad_ShortLogFile(t *testing.T) { // --- createIssueViaAPI --- -func TestCreateIssueViaAPI_Good_Success(t *testing.T) { +func TestIngest_CreateIssueViaAPI_Good_Success(t *testing.T) { called := false srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { called = true @@ -210,7 +210,7 @@ func TestCreateIssueViaAPI_Good_Success(t *testing.T) { assert.True(t, called) } -func TestCreateIssueViaAPI_Bad_NoBrainKey(t *testing.T) { +func TestIngest_CreateIssueViaAPI_Bad_NoBrainKey(t *testing.T) { s := &PrepSubsystem{ brainKey: "", backoff: make(map[string]time.Time), @@ -223,7 +223,7 @@ func TestCreateIssueViaAPI_Bad_NoBrainKey(t *testing.T) { }) } -func TestCreateIssueViaAPI_Bad_NoAPIKey(t *testing.T) { +func TestIngest_CreateIssueViaAPI_Bad_NoAPIKey(t *testing.T) { home := t.TempDir() t.Setenv("DIR_HOME", home) // No agent-api.key file @@ -242,7 +242,7 @@ func TestCreateIssueViaAPI_Bad_NoAPIKey(t *testing.T) { }) } -func TestCreateIssueViaAPI_Bad_ServerError(t *testing.T) { +func TestIngest_CreateIssueViaAPI_Bad_ServerError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) })) @@ -269,14 +269,14 @@ func TestCreateIssueViaAPI_Bad_ServerError(t *testing.T) { // --- countFileRefs (additional security-related) --- -func TestCountFileRefs_Good_SecurityFindings(t *testing.T) { +func TestIngest_CountFileRefs_Good_SecurityFindings(t *testing.T) { body := "Security scan found:\n" + "- `pkg/auth/token.go:55` hardcoded secret\n" + "- `pkg/auth/middleware.go:12` missing auth check\n" assert.Equal(t, 2, countFileRefs(body)) } -func TestCountFileRefs_Good_PHPSecurityFindings(t *testing.T) { +func TestIngest_CountFileRefs_Good_PHPSecurityFindings(t *testing.T) { body := "PHP audit:\n" + "- `src/Controller/Api.php:42` SQL injection risk\n" + "- `src/Service/Auth.php:100` session fixation\n" + diff --git a/pkg/agentic/logic_test.go b/pkg/agentic/logic_test.go index ec27aa1..e6f05ba 100644 --- a/pkg/agentic/logic_test.go +++ b/pkg/agentic/logic_test.go @@ -16,7 +16,7 @@ import ( // --- agentCommand --- -func TestAgentCommand_Good_Gemini(t *testing.T) { +func TestDispatch_AgentCommand_Good_Gemini(t *testing.T) { cmd, args, err := agentCommand("gemini", "do the thing") require.NoError(t, err) assert.Equal(t, "gemini", cmd) @@ -26,7 +26,7 @@ func TestAgentCommand_Good_Gemini(t *testing.T) { assert.Contains(t, args, "--sandbox") } -func TestAgentCommand_Good_GeminiWithModel(t *testing.T) { +func TestDispatch_AgentCommand_Good_GeminiWithModel(t *testing.T) { cmd, args, err := agentCommand("gemini:flash", "my prompt") require.NoError(t, err) assert.Equal(t, "gemini", cmd) @@ -34,7 +34,7 @@ func TestAgentCommand_Good_GeminiWithModel(t *testing.T) { assert.Contains(t, args, "gemini-2.5-flash") } -func TestAgentCommand_Good_Codex(t *testing.T) { +func TestDispatch_AgentCommand_Good_Codex(t *testing.T) { cmd, args, err := agentCommand("codex", "fix the tests") require.NoError(t, err) assert.Equal(t, "codex", cmd) @@ -43,7 +43,7 @@ func TestAgentCommand_Good_Codex(t *testing.T) { assert.Contains(t, args, "fix the tests") } -func TestAgentCommand_Good_CodexReview(t *testing.T) { +func TestDispatch_AgentCommand_Good_CodexReview(t *testing.T) { cmd, args, err := agentCommand("codex:review", "") require.NoError(t, err) assert.Equal(t, "codex", cmd) @@ -54,7 +54,7 @@ func TestAgentCommand_Good_CodexReview(t *testing.T) { } } -func TestAgentCommand_Good_CodexWithModel(t *testing.T) { +func TestDispatch_AgentCommand_Good_CodexWithModel(t *testing.T) { cmd, args, err := agentCommand("codex:gpt-5.4", "refactor this") require.NoError(t, err) assert.Equal(t, "codex", cmd) @@ -62,7 +62,7 @@ func TestAgentCommand_Good_CodexWithModel(t *testing.T) { assert.Contains(t, args, "gpt-5.4") } -func TestAgentCommand_Good_Claude(t *testing.T) { +func TestDispatch_AgentCommand_Good_Claude(t *testing.T) { cmd, args, err := agentCommand("claude", "add tests") require.NoError(t, err) assert.Equal(t, "claude", cmd) @@ -71,7 +71,7 @@ func TestAgentCommand_Good_Claude(t *testing.T) { assert.Contains(t, args, "--dangerously-skip-permissions") } -func TestAgentCommand_Good_ClaudeWithModel(t *testing.T) { +func TestDispatch_AgentCommand_Good_ClaudeWithModel(t *testing.T) { cmd, args, err := agentCommand("claude:haiku", "write docs") require.NoError(t, err) assert.Equal(t, "claude", cmd) @@ -79,7 +79,7 @@ func TestAgentCommand_Good_ClaudeWithModel(t *testing.T) { assert.Contains(t, args, "haiku") } -func TestAgentCommand_Good_CodeRabbit(t *testing.T) { +func TestDispatch_AgentCommand_Good_CodeRabbit(t *testing.T) { cmd, args, err := agentCommand("coderabbit", "") require.NoError(t, err) assert.Equal(t, "coderabbit", cmd) @@ -87,7 +87,7 @@ func TestAgentCommand_Good_CodeRabbit(t *testing.T) { assert.Contains(t, args, "--plain") } -func TestAgentCommand_Good_Local(t *testing.T) { +func TestDispatch_AgentCommand_Good_Local(t *testing.T) { cmd, args, err := agentCommand("local", "do stuff") require.NoError(t, err) assert.Equal(t, "sh", cmd) @@ -97,21 +97,21 @@ func TestAgentCommand_Good_Local(t *testing.T) { assert.Contains(t, args[1], "devstral-24b") } -func TestAgentCommand_Good_LocalWithModel(t *testing.T) { +func TestDispatch_AgentCommand_Good_LocalWithModel(t *testing.T) { cmd, args, err := agentCommand("local:mistral-nemo", "do stuff") require.NoError(t, err) assert.Equal(t, "sh", cmd) assert.Contains(t, args[1], "mistral-nemo") } -func TestAgentCommand_Bad_Unknown(t *testing.T) { +func TestDispatch_AgentCommand_Bad_Unknown(t *testing.T) { cmd, args, err := agentCommand("robot-from-the-future", "take over") assert.Error(t, err) assert.Empty(t, cmd) assert.Nil(t, args) } -func TestAgentCommand_Ugly_EmptyAgent(t *testing.T) { +func TestDispatch_AgentCommand_Ugly_EmptyAgent(t *testing.T) { cmd, args, err := agentCommand("", "prompt") assert.Error(t, err) assert.Empty(t, cmd) @@ -120,7 +120,7 @@ func TestAgentCommand_Ugly_EmptyAgent(t *testing.T) { // --- containerCommand --- -func TestContainerCommand_Good_Codex(t *testing.T) { +func TestDispatch_ContainerCommand_Good_Codex(t *testing.T) { t.Setenv("AGENT_DOCKER_IMAGE", "") t.Setenv("DIR_HOME", "/home/dev") @@ -135,7 +135,7 @@ func TestContainerCommand_Good_Codex(t *testing.T) { assert.Contains(t, args, defaultDockerImage) } -func TestContainerCommand_Good_CustomImage(t *testing.T) { +func TestDispatch_ContainerCommand_Good_CustomImage(t *testing.T) { t.Setenv("AGENT_DOCKER_IMAGE", "my-custom-image:latest") t.Setenv("DIR_HOME", "/home/dev") @@ -144,7 +144,7 @@ func TestContainerCommand_Good_CustomImage(t *testing.T) { assert.Contains(t, args, "my-custom-image:latest") } -func TestContainerCommand_Good_ClaudeMountsConfig(t *testing.T) { +func TestDispatch_ContainerCommand_Good_ClaudeMountsConfig(t *testing.T) { t.Setenv("AGENT_DOCKER_IMAGE", "") t.Setenv("DIR_HOME", "/home/dev") @@ -153,7 +153,7 @@ func TestContainerCommand_Good_ClaudeMountsConfig(t *testing.T) { assert.Contains(t, joined, ".claude:/home/dev/.claude:ro") } -func TestContainerCommand_Good_GeminiMountsConfig(t *testing.T) { +func TestDispatch_ContainerCommand_Good_GeminiMountsConfig(t *testing.T) { t.Setenv("AGENT_DOCKER_IMAGE", "") t.Setenv("DIR_HOME", "/home/dev") @@ -162,7 +162,7 @@ func TestContainerCommand_Good_GeminiMountsConfig(t *testing.T) { assert.Contains(t, joined, ".gemini:/home/dev/.gemini:ro") } -func TestContainerCommand_Good_CodexNoClaudeMount(t *testing.T) { +func TestDispatch_ContainerCommand_Good_CodexNoClaudeMount(t *testing.T) { t.Setenv("AGENT_DOCKER_IMAGE", "") t.Setenv("DIR_HOME", "/home/dev") @@ -172,7 +172,7 @@ func TestContainerCommand_Good_CodexNoClaudeMount(t *testing.T) { assert.NotContains(t, joined, ".claude:/home/dev/.claude:ro") } -func TestContainerCommand_Good_APIKeysPassedByRef(t *testing.T) { +func TestDispatch_ContainerCommand_Good_APIKeysPassedByRef(t *testing.T) { t.Setenv("AGENT_DOCKER_IMAGE", "") t.Setenv("DIR_HOME", "/home/dev") @@ -183,7 +183,7 @@ func TestContainerCommand_Good_APIKeysPassedByRef(t *testing.T) { assert.Contains(t, joined, "GEMINI_API_KEY") } -func TestContainerCommand_Ugly_EmptyDirs(t *testing.T) { +func TestDispatch_ContainerCommand_Ugly_EmptyDirs(t *testing.T) { t.Setenv("AGENT_DOCKER_IMAGE", "") t.Setenv("DIR_HOME", "") @@ -195,7 +195,7 @@ func TestContainerCommand_Ugly_EmptyDirs(t *testing.T) { // --- buildAutoPRBody --- -func TestBuildAutoPRBody_Good_Basic(t *testing.T) { +func TestAutoPr_BuildAutoPRBody_Good_Basic(t *testing.T) { s := &PrepSubsystem{} st := &WorkspaceStatus{ Task: "Fix the login bug", @@ -210,7 +210,7 @@ func TestBuildAutoPRBody_Good_Basic(t *testing.T) { assert.Contains(t, body, "Co-Authored-By: Virgil ") } -func TestBuildAutoPRBody_Good_WithIssue(t *testing.T) { +func TestAutoPr_BuildAutoPRBody_Good_WithIssue(t *testing.T) { s := &PrepSubsystem{} st := &WorkspaceStatus{ Task: "Add rate limiting", @@ -222,7 +222,7 @@ func TestBuildAutoPRBody_Good_WithIssue(t *testing.T) { assert.Contains(t, body, "Closes #42") } -func TestBuildAutoPRBody_Good_NoIssue(t *testing.T) { +func TestAutoPr_BuildAutoPRBody_Good_NoIssue(t *testing.T) { s := &PrepSubsystem{} st := &WorkspaceStatus{ Task: "Refactor internals", @@ -233,7 +233,7 @@ func TestBuildAutoPRBody_Good_NoIssue(t *testing.T) { assert.NotContains(t, body, "Closes #") } -func TestBuildAutoPRBody_Good_CommitCount(t *testing.T) { +func TestAutoPr_BuildAutoPRBody_Good_CommitCount(t *testing.T) { s := &PrepSubsystem{} st := &WorkspaceStatus{Agent: "codex", Branch: "agent/foo"} body1 := s.buildAutoPRBody(st, 1) @@ -242,7 +242,7 @@ func TestBuildAutoPRBody_Good_CommitCount(t *testing.T) { assert.Contains(t, body5, "**Commits:** 5") } -func TestBuildAutoPRBody_Bad_EmptyTask(t *testing.T) { +func TestAutoPr_BuildAutoPRBody_Bad_EmptyTask(t *testing.T) { s := &PrepSubsystem{} st := &WorkspaceStatus{ Task: "", @@ -255,7 +255,7 @@ func TestBuildAutoPRBody_Bad_EmptyTask(t *testing.T) { assert.Contains(t, body, "**Agent:** codex") } -func TestBuildAutoPRBody_Ugly_ZeroCommits(t *testing.T) { +func TestAutoPr_BuildAutoPRBody_Ugly_ZeroCommits(t *testing.T) { s := &PrepSubsystem{} st := &WorkspaceStatus{Agent: "codex", Branch: "agent/test"} body := s.buildAutoPRBody(st, 0) @@ -264,7 +264,7 @@ func TestBuildAutoPRBody_Ugly_ZeroCommits(t *testing.T) { // --- emitEvent --- -func TestEmitEvent_Good_WritesJSONL(t *testing.T) { +func TestEvents_EmitEvent_Good_WritesJSONL(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) require.True(t, fs.EnsureDir(filepath.Join(root, "workspace")).OK) @@ -282,7 +282,7 @@ func TestEmitEvent_Good_WritesJSONL(t *testing.T) { assert.Contains(t, content, "completed") } -func TestEmitEvent_Good_ValidJSON(t *testing.T) { +func TestEvents_EmitEvent_Good_ValidJSON(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) require.True(t, fs.EnsureDir(filepath.Join(root, "workspace")).OK) @@ -306,7 +306,7 @@ func TestEmitEvent_Good_ValidJSON(t *testing.T) { } } -func TestEmitEvent_Good_Appends(t *testing.T) { +func TestEvents_EmitEvent_Good_Appends(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) require.True(t, fs.EnsureDir(filepath.Join(root, "workspace")).OK) @@ -327,7 +327,7 @@ func TestEmitEvent_Good_Appends(t *testing.T) { assert.Equal(t, 2, lines, "both events should be in the log") } -func TestEmitEvent_Good_StartHelper(t *testing.T) { +func TestEvents_EmitEvent_Good_StartHelper(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) require.True(t, fs.EnsureDir(filepath.Join(root, "workspace")).OK) @@ -341,7 +341,7 @@ func TestEmitEvent_Good_StartHelper(t *testing.T) { assert.Contains(t, r.Value.(string), "running") } -func TestEmitEvent_Good_CompletionHelper(t *testing.T) { +func TestEvents_EmitEvent_Good_CompletionHelper(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) require.True(t, fs.EnsureDir(filepath.Join(root, "workspace")).OK) @@ -355,7 +355,7 @@ func TestEmitEvent_Good_CompletionHelper(t *testing.T) { assert.Contains(t, r.Value.(string), "failed") } -func TestEmitEvent_Bad_NoWorkspaceDir(t *testing.T) { +func TestEvents_EmitEvent_Bad_NoWorkspaceDir(t *testing.T) { // CORE_WORKSPACE points to a directory that doesn't allow writing events.jsonl // because workspace/ subdir doesn't exist. Should not panic. root := t.TempDir() @@ -366,7 +366,7 @@ func TestEmitEvent_Bad_NoWorkspaceDir(t *testing.T) { }) } -func TestEmitEvent_Ugly_EmptyFields(t *testing.T) { +func TestEvents_EmitEvent_Ugly_EmptyFields(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) require.True(t, fs.EnsureDir(filepath.Join(root, "workspace")).OK) @@ -379,42 +379,42 @@ func TestEmitEvent_Ugly_EmptyFields(t *testing.T) { // --- countFileRefs --- -func TestCountFileRefs_Good_GoRefs(t *testing.T) { +func TestIngest_CountFileRefs_Good_GoRefs(t *testing.T) { body := "Found issue in `pkg/core/app.go:42` and `pkg/core/service.go:100`." assert.Equal(t, 2, countFileRefs(body)) } -func TestCountFileRefs_Good_PHPRefs(t *testing.T) { +func TestIngest_CountFileRefs_Good_PHPRefs(t *testing.T) { body := "See `src/Core/Boot.php:15` for details." assert.Equal(t, 1, countFileRefs(body)) } -func TestCountFileRefs_Good_Mixed(t *testing.T) { +func TestIngest_CountFileRefs_Good_Mixed(t *testing.T) { body := "Go file: `main.go:1`, PHP file: `index.php:99`, plain text ref." assert.Equal(t, 2, countFileRefs(body)) } -func TestCountFileRefs_Good_NoRefs(t *testing.T) { +func TestIngest_CountFileRefs_Good_NoRefs(t *testing.T) { body := "This is just plain text with no file references." assert.Equal(t, 0, countFileRefs(body)) } -func TestCountFileRefs_Good_UnrelatedBacktick(t *testing.T) { +func TestIngest_CountFileRefs_Good_UnrelatedBacktick(t *testing.T) { // Backtick-quoted string that is not a file:line reference body := "Run `go test ./...` to execute tests." assert.Equal(t, 0, countFileRefs(body)) } -func TestCountFileRefs_Bad_EmptyBody(t *testing.T) { +func TestIngest_CountFileRefs_Bad_EmptyBody(t *testing.T) { assert.Equal(t, 0, countFileRefs("")) } -func TestCountFileRefs_Bad_ShortBody(t *testing.T) { +func TestIngest_CountFileRefs_Bad_ShortBody(t *testing.T) { // Body too short to contain a valid reference assert.Equal(t, 0, countFileRefs("`a`")) } -func TestCountFileRefs_Ugly_MalformedBackticks(t *testing.T) { +func TestIngest_CountFileRefs_Ugly_MalformedBackticks(t *testing.T) { // Unclosed backtick — should not panic or hang body := "Something `unclosed" assert.NotPanics(t, func() { @@ -422,7 +422,7 @@ func TestCountFileRefs_Ugly_MalformedBackticks(t *testing.T) { }) } -func TestCountFileRefs_Ugly_LongRef(t *testing.T) { +func TestIngest_CountFileRefs_Ugly_LongRef(t *testing.T) { // Reference longer than 100 chars should not be counted (loop limit) longRef := "`" + strings.Repeat("a", 101) + ".go:1`" assert.Equal(t, 0, countFileRefs(longRef)) @@ -430,67 +430,67 @@ func TestCountFileRefs_Ugly_LongRef(t *testing.T) { // --- modelVariant --- -func TestModelVariant_Good_WithModel(t *testing.T) { +func TestQueue_ModelVariant_Good_WithModel(t *testing.T) { assert.Equal(t, "gpt-5.4", modelVariant("codex:gpt-5.4")) assert.Equal(t, "flash", modelVariant("gemini:flash")) assert.Equal(t, "opus", modelVariant("claude:opus")) assert.Equal(t, "haiku", modelVariant("claude:haiku")) } -func TestModelVariant_Good_NoVariant(t *testing.T) { +func TestQueue_ModelVariant_Good_NoVariant(t *testing.T) { assert.Equal(t, "", modelVariant("codex")) assert.Equal(t, "", modelVariant("claude")) assert.Equal(t, "", modelVariant("gemini")) } -func TestModelVariant_Good_MultipleColons(t *testing.T) { +func TestQueue_ModelVariant_Good_MultipleColons(t *testing.T) { // SplitN(2) only splits on first colon; rest is preserved as the model assert.Equal(t, "gpt-5.3-codex-spark", modelVariant("codex:gpt-5.3-codex-spark")) } -func TestModelVariant_Bad_EmptyString(t *testing.T) { +func TestQueue_ModelVariant_Bad_EmptyString(t *testing.T) { assert.Equal(t, "", modelVariant("")) } -func TestModelVariant_Ugly_ColonOnly(t *testing.T) { +func TestQueue_ModelVariant_Ugly_ColonOnly(t *testing.T) { // Just a colon with no model name assert.Equal(t, "", modelVariant(":")) } // --- baseAgent --- -func TestBaseAgent_Good_Variants(t *testing.T) { +func TestQueue_BaseAgent_Good_Variants(t *testing.T) { assert.Equal(t, "gemini", baseAgent("gemini:flash")) assert.Equal(t, "gemini", baseAgent("gemini:pro")) assert.Equal(t, "claude", baseAgent("claude:haiku")) assert.Equal(t, "codex", baseAgent("codex:gpt-5.4")) } -func TestBaseAgent_Good_NoVariant(t *testing.T) { +func TestQueue_BaseAgent_Good_NoVariant(t *testing.T) { assert.Equal(t, "codex", baseAgent("codex")) assert.Equal(t, "claude", baseAgent("claude")) assert.Equal(t, "gemini", baseAgent("gemini")) } -func TestBaseAgent_Good_CodexSparkSpecialCase(t *testing.T) { +func TestQueue_BaseAgent_Good_CodexSparkSpecialCase(t *testing.T) { // codex-spark variants map to their own pool name assert.Equal(t, "codex-spark", baseAgent("codex:gpt-5.3-codex-spark")) assert.Equal(t, "codex-spark", baseAgent("codex-spark")) } -func TestBaseAgent_Bad_EmptyString(t *testing.T) { +func TestQueue_BaseAgent_Bad_EmptyString(t *testing.T) { // Empty string — SplitN returns [""], so first element is "" assert.Equal(t, "", baseAgent("")) } -func TestBaseAgent_Ugly_JustColon(t *testing.T) { +func TestQueue_BaseAgent_Ugly_JustColon(t *testing.T) { // Just a colon — base is empty string before colon assert.Equal(t, "", baseAgent(":model")) } // --- resolveWorkspace --- -func TestResolveWorkspace_Good_ExistingDir(t *testing.T) { +func TestHandlers_ResolveWorkspace_Good_ExistingDir(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -503,7 +503,7 @@ func TestResolveWorkspace_Good_ExistingDir(t *testing.T) { assert.Equal(t, wsDir, result) } -func TestResolveWorkspace_Good_NestedPath(t *testing.T) { +func TestHandlers_ResolveWorkspace_Good_NestedPath(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -515,7 +515,7 @@ func TestResolveWorkspace_Good_NestedPath(t *testing.T) { assert.Equal(t, wsDir, result) } -func TestResolveWorkspace_Bad_NonExistentDir(t *testing.T) { +func TestHandlers_ResolveWorkspace_Bad_NonExistentDir(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -523,7 +523,7 @@ func TestResolveWorkspace_Bad_NonExistentDir(t *testing.T) { assert.Equal(t, "", result) } -func TestResolveWorkspace_Bad_EmptyName(t *testing.T) { +func TestHandlers_ResolveWorkspace_Bad_EmptyName(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -535,7 +535,7 @@ func TestResolveWorkspace_Bad_EmptyName(t *testing.T) { _ = result } -func TestResolveWorkspace_Ugly_PathTraversal(t *testing.T) { +func TestHandlers_ResolveWorkspace_Ugly_PathTraversal(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -546,7 +546,7 @@ func TestResolveWorkspace_Ugly_PathTraversal(t *testing.T) { // --- findWorkspaceByPR --- -func TestFindWorkspaceByPR_Good_MatchesFlatLayout(t *testing.T) { +func TestHandlers_FindWorkspaceByPR_Good_MatchesFlatLayout(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -562,7 +562,7 @@ func TestFindWorkspaceByPR_Good_MatchesFlatLayout(t *testing.T) { assert.Equal(t, wsDir, result) } -func TestFindWorkspaceByPR_Good_MatchesDeepLayout(t *testing.T) { +func TestHandlers_FindWorkspaceByPR_Good_MatchesDeepLayout(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -578,7 +578,7 @@ func TestFindWorkspaceByPR_Good_MatchesDeepLayout(t *testing.T) { assert.Equal(t, wsDir, result) } -func TestFindWorkspaceByPR_Bad_NoMatch(t *testing.T) { +func TestHandlers_FindWorkspaceByPR_Bad_NoMatch(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -594,7 +594,7 @@ func TestFindWorkspaceByPR_Bad_NoMatch(t *testing.T) { assert.Equal(t, "", result) } -func TestFindWorkspaceByPR_Bad_EmptyWorkspace(t *testing.T) { +func TestHandlers_FindWorkspaceByPR_Bad_EmptyWorkspace(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) // No workspaces at all @@ -602,7 +602,7 @@ func TestFindWorkspaceByPR_Bad_EmptyWorkspace(t *testing.T) { assert.Equal(t, "", result) } -func TestFindWorkspaceByPR_Bad_RepoDiffers(t *testing.T) { +func TestHandlers_FindWorkspaceByPR_Bad_RepoDiffers(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -619,7 +619,7 @@ func TestFindWorkspaceByPR_Bad_RepoDiffers(t *testing.T) { assert.Equal(t, "", result) } -func TestFindWorkspaceByPR_Ugly_CorruptStatusFile(t *testing.T) { +func TestHandlers_FindWorkspaceByPR_Ugly_CorruptStatusFile(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -634,31 +634,31 @@ func TestFindWorkspaceByPR_Ugly_CorruptStatusFile(t *testing.T) { // --- extractPRNumber --- -func TestExtractPRNumber_Good_FullURL(t *testing.T) { +func TestVerify_ExtractPRNumber_Good_FullURL(t *testing.T) { assert.Equal(t, 42, extractPRNumber("https://forge.lthn.ai/core/agent/pulls/42")) assert.Equal(t, 1, extractPRNumber("https://forge.lthn.ai/core/go-io/pulls/1")) assert.Equal(t, 999, extractPRNumber("https://forge.lthn.ai/core/go-log/pulls/999")) } -func TestExtractPRNumber_Good_NumberOnly(t *testing.T) { +func TestVerify_ExtractPRNumber_Good_NumberOnly(t *testing.T) { // If someone passes a bare number as a URL it should still work assert.Equal(t, 7, extractPRNumber("7")) } -func TestExtractPRNumber_Bad_EmptyURL(t *testing.T) { +func TestVerify_ExtractPRNumber_Bad_EmptyURL(t *testing.T) { assert.Equal(t, 0, extractPRNumber("")) } -func TestExtractPRNumber_Bad_TrailingSlash(t *testing.T) { +func TestVerify_ExtractPRNumber_Bad_TrailingSlash(t *testing.T) { // URL ending with slash has empty last segment assert.Equal(t, 0, extractPRNumber("https://forge.lthn.ai/core/go-io/pulls/")) } -func TestExtractPRNumber_Bad_NonNumericEnd(t *testing.T) { +func TestVerify_ExtractPRNumber_Bad_NonNumericEnd(t *testing.T) { assert.Equal(t, 0, extractPRNumber("https://forge.lthn.ai/core/go-io/pulls/abc")) } -func TestExtractPRNumber_Ugly_JustSlashes(t *testing.T) { +func TestVerify_ExtractPRNumber_Ugly_JustSlashes(t *testing.T) { // All slashes — last segment is empty assert.Equal(t, 0, extractPRNumber("///")) } diff --git a/pkg/agentic/mirror_test.go b/pkg/agentic/mirror_test.go index 229f870..7d46049 100644 --- a/pkg/agentic/mirror_test.go +++ b/pkg/agentic/mirror_test.go @@ -41,7 +41,7 @@ func initBareRepo(t *testing.T) string { // --- hasRemote --- -func TestHasRemote_Good_OriginExists(t *testing.T) { +func TestMirror_HasRemote_Good_OriginExists(t *testing.T) { dir := initBareRepo(t) // origin won't exist for a fresh repo, so add it cmd := exec.Command("git", "remote", "add", "origin", "https://example.com/repo.git") @@ -51,7 +51,7 @@ func TestHasRemote_Good_OriginExists(t *testing.T) { assert.True(t, hasRemote(dir, "origin")) } -func TestHasRemote_Good_CustomRemote(t *testing.T) { +func TestMirror_HasRemote_Good_CustomRemote(t *testing.T) { dir := initBareRepo(t) cmd := exec.Command("git", "remote", "add", "github", "https://github.com/test/repo.git") cmd.Dir = dir @@ -60,17 +60,17 @@ func TestHasRemote_Good_CustomRemote(t *testing.T) { assert.True(t, hasRemote(dir, "github")) } -func TestHasRemote_Bad_NoSuchRemote(t *testing.T) { +func TestMirror_HasRemote_Bad_NoSuchRemote(t *testing.T) { dir := initBareRepo(t) assert.False(t, hasRemote(dir, "nonexistent")) } -func TestHasRemote_Bad_NotAGitRepo(t *testing.T) { +func TestMirror_HasRemote_Bad_NotAGitRepo(t *testing.T) { dir := t.TempDir() // plain directory, no .git assert.False(t, hasRemote(dir, "origin")) } -func TestHasRemote_Ugly_EmptyDir(t *testing.T) { +func TestMirror_HasRemote_Ugly_EmptyDir(t *testing.T) { // Empty dir defaults to cwd which may or may not be a repo. // Just ensure no panic. assert.NotPanics(t, func() { @@ -80,7 +80,7 @@ func TestHasRemote_Ugly_EmptyDir(t *testing.T) { // --- commitsAhead --- -func TestCommitsAhead_Good_OneAhead(t *testing.T) { +func TestMirror_CommitsAhead_Good_OneAhead(t *testing.T) { dir := initBareRepo(t) // Create a branch at the current commit to act as "base" @@ -109,7 +109,7 @@ func TestCommitsAhead_Good_OneAhead(t *testing.T) { assert.Equal(t, 1, ahead) } -func TestCommitsAhead_Good_ThreeAhead(t *testing.T) { +func TestMirror_CommitsAhead_Good_ThreeAhead(t *testing.T) { dir := initBareRepo(t) run := func(args ...string) { t.Helper() @@ -138,32 +138,32 @@ func TestCommitsAhead_Good_ThreeAhead(t *testing.T) { assert.Equal(t, 3, ahead) } -func TestCommitsAhead_Good_ZeroAhead(t *testing.T) { +func TestMirror_CommitsAhead_Good_ZeroAhead(t *testing.T) { dir := initBareRepo(t) // Same ref on both sides ahead := commitsAhead(dir, "main", "main") assert.Equal(t, 0, ahead) } -func TestCommitsAhead_Bad_InvalidRef(t *testing.T) { +func TestMirror_CommitsAhead_Bad_InvalidRef(t *testing.T) { dir := initBareRepo(t) ahead := commitsAhead(dir, "nonexistent-ref", "main") assert.Equal(t, 0, ahead) } -func TestCommitsAhead_Bad_NotARepo(t *testing.T) { +func TestMirror_CommitsAhead_Bad_NotARepo(t *testing.T) { ahead := commitsAhead(t.TempDir(), "main", "dev") assert.Equal(t, 0, ahead) } -func TestCommitsAhead_Ugly_EmptyDir(t *testing.T) { +func TestMirror_CommitsAhead_Ugly_EmptyDir(t *testing.T) { ahead := commitsAhead("", "a", "b") assert.Equal(t, 0, ahead) } // --- filesChanged --- -func TestFilesChanged_Good_OneFile(t *testing.T) { +func TestMirror_FilesChanged_Good_OneFile(t *testing.T) { dir := initBareRepo(t) run := func(args ...string) { t.Helper() @@ -189,7 +189,7 @@ func TestFilesChanged_Good_OneFile(t *testing.T) { assert.Equal(t, 1, files) } -func TestFilesChanged_Good_MultipleFiles(t *testing.T) { +func TestMirror_FilesChanged_Good_MultipleFiles(t *testing.T) { dir := initBareRepo(t) run := func(args ...string) { t.Helper() @@ -217,92 +217,92 @@ func TestFilesChanged_Good_MultipleFiles(t *testing.T) { assert.Equal(t, 3, files) } -func TestFilesChanged_Good_NoChanges(t *testing.T) { +func TestMirror_FilesChanged_Good_NoChanges(t *testing.T) { dir := initBareRepo(t) files := filesChanged(dir, "main", "main") assert.Equal(t, 0, files) } -func TestFilesChanged_Bad_InvalidRef(t *testing.T) { +func TestMirror_FilesChanged_Bad_InvalidRef(t *testing.T) { dir := initBareRepo(t) files := filesChanged(dir, "nonexistent", "main") assert.Equal(t, 0, files) } -func TestFilesChanged_Bad_NotARepo(t *testing.T) { +func TestMirror_FilesChanged_Bad_NotARepo(t *testing.T) { files := filesChanged(t.TempDir(), "main", "dev") assert.Equal(t, 0, files) } -func TestFilesChanged_Ugly_EmptyDir(t *testing.T) { +func TestMirror_FilesChanged_Ugly_EmptyDir(t *testing.T) { files := filesChanged("", "a", "b") assert.Equal(t, 0, files) } // --- extractJSONField (extending existing 91% coverage) --- -func TestExtractJSONField_Good_ArrayFirstItem(t *testing.T) { +func TestMirror_ExtractJSONField_Good_ArrayFirstItem(t *testing.T) { json := `[{"url":"https://github.com/test/pr/1","title":"Fix bug"}]` assert.Equal(t, "https://github.com/test/pr/1", extractJSONField(json, "url")) } -func TestExtractJSONField_Good_ObjectField(t *testing.T) { +func TestMirror_ExtractJSONField_Good_ObjectField(t *testing.T) { json := `{"name":"test-repo","status":"active"}` assert.Equal(t, "test-repo", extractJSONField(json, "name")) } -func TestExtractJSONField_Good_ArrayMultipleItems(t *testing.T) { +func TestMirror_ExtractJSONField_Good_ArrayMultipleItems(t *testing.T) { json := `[{"id":"first"},{"id":"second"}]` // Should return the first match assert.Equal(t, "first", extractJSONField(json, "id")) } -func TestExtractJSONField_Bad_EmptyJSON(t *testing.T) { +func TestMirror_ExtractJSONField_Bad_EmptyJSON(t *testing.T) { assert.Equal(t, "", extractJSONField("", "url")) } -func TestExtractJSONField_Bad_EmptyField(t *testing.T) { +func TestMirror_ExtractJSONField_Bad_EmptyField(t *testing.T) { assert.Equal(t, "", extractJSONField(`{"url":"test"}`, "")) } -func TestExtractJSONField_Bad_FieldNotFound(t *testing.T) { +func TestMirror_ExtractJSONField_Bad_FieldNotFound(t *testing.T) { json := `{"name":"test"}` assert.Equal(t, "", extractJSONField(json, "missing")) } -func TestExtractJSONField_Bad_InvalidJSON(t *testing.T) { +func TestMirror_ExtractJSONField_Bad_InvalidJSON(t *testing.T) { assert.Equal(t, "", extractJSONField("not json at all", "url")) } -func TestExtractJSONField_Ugly_EmptyArray(t *testing.T) { +func TestMirror_ExtractJSONField_Ugly_EmptyArray(t *testing.T) { assert.Equal(t, "", extractJSONField("[]", "url")) } -func TestExtractJSONField_Ugly_EmptyObject(t *testing.T) { +func TestMirror_ExtractJSONField_Ugly_EmptyObject(t *testing.T) { assert.Equal(t, "", extractJSONField("{}", "url")) } -func TestExtractJSONField_Ugly_NumericValue(t *testing.T) { +func TestMirror_ExtractJSONField_Ugly_NumericValue(t *testing.T) { // Field exists but is not a string — should return "" json := `{"count":42}` assert.Equal(t, "", extractJSONField(json, "count")) } -func TestExtractJSONField_Ugly_NullValue(t *testing.T) { +func TestMirror_ExtractJSONField_Ugly_NullValue(t *testing.T) { json := `{"url":null}` assert.Equal(t, "", extractJSONField(json, "url")) } // --- DefaultBranch --- -func TestDefaultBranch_Good_MainBranch(t *testing.T) { +func TestPaths_DefaultBranch_Good_MainBranch(t *testing.T) { dir := initBareRepo(t) // initBareRepo creates with -b main branch := DefaultBranch(dir) assert.Equal(t, "main", branch) } -func TestDefaultBranch_Bad_NotARepo(t *testing.T) { +func TestPaths_DefaultBranch_Bad_NotARepo(t *testing.T) { dir := t.TempDir() // Falls back to "main" when detection fails branch := DefaultBranch(dir) @@ -311,7 +311,7 @@ func TestDefaultBranch_Bad_NotARepo(t *testing.T) { // --- listLocalRepos --- -func TestListLocalRepos_Good_FindsRepos(t *testing.T) { +func TestMirror_ListLocalRepos_Good_FindsRepos(t *testing.T) { base := t.TempDir() // Create two git repos under base @@ -331,14 +331,14 @@ func TestListLocalRepos_Good_FindsRepos(t *testing.T) { assert.NotContains(t, repos, "not-a-repo") } -func TestListLocalRepos_Bad_EmptyDir(t *testing.T) { +func TestMirror_ListLocalRepos_Bad_EmptyDir(t *testing.T) { base := t.TempDir() s := &PrepSubsystem{} repos := s.listLocalRepos(base) assert.Empty(t, repos) } -func TestListLocalRepos_Bad_NonExistentDir(t *testing.T) { +func TestMirror_ListLocalRepos_Bad_NonExistentDir(t *testing.T) { s := &PrepSubsystem{} repos := s.listLocalRepos("/nonexistent/path/that/doesnt/exist") assert.Nil(t, repos) @@ -346,12 +346,12 @@ func TestListLocalRepos_Bad_NonExistentDir(t *testing.T) { // --- GitHubOrg --- -func TestGitHubOrg_Good_Default(t *testing.T) { +func TestPaths_GitHubOrg_Good_Default(t *testing.T) { t.Setenv("GITHUB_ORG", "") assert.Equal(t, "dAppCore", GitHubOrg()) } -func TestGitHubOrg_Good_Custom(t *testing.T) { +func TestPaths_GitHubOrg_Good_Custom(t *testing.T) { t.Setenv("GITHUB_ORG", "my-org") assert.Equal(t, "my-org", GitHubOrg()) } diff --git a/pkg/agentic/paths_test.go b/pkg/agentic/paths_test.go index 68fb28e..29cab3c 100644 --- a/pkg/agentic/paths_test.go +++ b/pkg/agentic/paths_test.go @@ -12,134 +12,134 @@ import ( "github.com/stretchr/testify/require" ) -func TestCoreRoot_Good_EnvVar(t *testing.T) { +func TestPaths_CoreRoot_Good_EnvVar(t *testing.T) { t.Setenv("CORE_WORKSPACE", "/tmp/test-core") assert.Equal(t, "/tmp/test-core", CoreRoot()) } -func TestCoreRoot_Good_Fallback(t *testing.T) { +func TestPaths_CoreRoot_Good_Fallback(t *testing.T) { t.Setenv("CORE_WORKSPACE", "") home, _ := os.UserHomeDir() assert.Equal(t, home+"/Code/.core", CoreRoot()) } -func TestWorkspaceRoot_Good(t *testing.T) { +func TestPaths_WorkspaceRoot_Good(t *testing.T) { t.Setenv("CORE_WORKSPACE", "/tmp/test-core") assert.Equal(t, "/tmp/test-core/workspace", WorkspaceRoot()) } -func TestPlansRoot_Good(t *testing.T) { +func TestPaths_PlansRoot_Good(t *testing.T) { t.Setenv("CORE_WORKSPACE", "/tmp/test-core") assert.Equal(t, "/tmp/test-core/plans", PlansRoot()) } -func TestAgentName_Good_EnvVar(t *testing.T) { +func TestPaths_AgentName_Good_EnvVar(t *testing.T) { t.Setenv("AGENT_NAME", "clotho") assert.Equal(t, "clotho", AgentName()) } -func TestAgentName_Good_Fallback(t *testing.T) { +func TestPaths_AgentName_Good_Fallback(t *testing.T) { t.Setenv("AGENT_NAME", "") name := AgentName() assert.True(t, name == "cladius" || name == "charon", "expected cladius or charon, got %s", name) } -func TestGitHubOrg_Good_EnvVar(t *testing.T) { +func TestPaths_GitHubOrg_Good_EnvVar(t *testing.T) { t.Setenv("GITHUB_ORG", "myorg") assert.Equal(t, "myorg", GitHubOrg()) } -func TestGitHubOrg_Good_Fallback(t *testing.T) { +func TestPaths_GitHubOrg_Good_Fallback(t *testing.T) { t.Setenv("GITHUB_ORG", "") assert.Equal(t, "dAppCore", GitHubOrg()) } -func TestBaseAgent_Good(t *testing.T) { +func TestQueue_BaseAgent_Good(t *testing.T) { assert.Equal(t, "claude", baseAgent("claude:opus")) assert.Equal(t, "claude", baseAgent("claude:haiku")) assert.Equal(t, "gemini", baseAgent("gemini:flash")) assert.Equal(t, "codex", baseAgent("codex")) } -func TestExtractPRNumber_Good(t *testing.T) { +func TestVerify_ExtractPRNumber_Good(t *testing.T) { assert.Equal(t, 123, extractPRNumber("https://forge.lthn.ai/core/go-io/pulls/123")) assert.Equal(t, 1, extractPRNumber("https://forge.lthn.ai/core/agent/pulls/1")) } -func TestExtractPRNumber_Bad_Empty(t *testing.T) { +func TestVerify_ExtractPRNumber_Bad_Empty(t *testing.T) { assert.Equal(t, 0, extractPRNumber("")) assert.Equal(t, 0, extractPRNumber("https://forge.lthn.ai/core/agent/pulls/")) } -func TestTruncate_Good(t *testing.T) { +func TestAutoPr_Truncate_Good(t *testing.T) { assert.Equal(t, "hello", truncate("hello", 10)) assert.Equal(t, "hel...", truncate("hello world", 3)) } -func TestCountFindings_Good(t *testing.T) { +func TestReviewQueue_CountFindings_Good(t *testing.T) { assert.Equal(t, 0, countFindings("No findings")) assert.Equal(t, 2, countFindings("- Issue one\n- Issue two\nSummary")) assert.Equal(t, 1, countFindings("⚠ Warning here")) } -func TestParseRetryAfter_Good(t *testing.T) { +func TestReviewQueue_ParseRetryAfter_Good(t *testing.T) { d := parseRetryAfter("please try after 4 minutes and 56 seconds") assert.InDelta(t, 296.0, d.Seconds(), 1.0) } -func TestParseRetryAfter_Good_MinutesOnly(t *testing.T) { +func TestReviewQueue_ParseRetryAfter_Good_MinutesOnly(t *testing.T) { d := parseRetryAfter("try after 5 minutes") assert.InDelta(t, 300.0, d.Seconds(), 1.0) } -func TestParseRetryAfter_Bad_NoMatch(t *testing.T) { +func TestReviewQueue_ParseRetryAfter_Bad_NoMatch(t *testing.T) { d := parseRetryAfter("some random text") assert.InDelta(t, 300.0, d.Seconds(), 1.0) // defaults to 5 min } -func TestResolveHost_Good(t *testing.T) { +func TestRemote_ResolveHost_Good(t *testing.T) { assert.Equal(t, "10.69.69.165:9101", resolveHost("charon")) assert.Equal(t, "127.0.0.1:9101", resolveHost("cladius")) assert.Equal(t, "127.0.0.1:9101", resolveHost("local")) } -func TestResolveHost_Good_CustomPort(t *testing.T) { +func TestRemote_ResolveHost_Good_CustomPort(t *testing.T) { assert.Equal(t, "192.168.1.1:9101", resolveHost("192.168.1.1")) assert.Equal(t, "192.168.1.1:8080", resolveHost("192.168.1.1:8080")) } -func TestExtractJSONField_Good(t *testing.T) { +func TestMirror_ExtractJSONField_Good(t *testing.T) { json := `[{"url":"https://github.com/dAppCore/go-io/pull/1"}]` assert.Equal(t, "https://github.com/dAppCore/go-io/pull/1", extractJSONField(json, "url")) } -func TestExtractJSONField_Good_Object(t *testing.T) { +func TestMirror_ExtractJSONField_Good_Object(t *testing.T) { json := `{"url":"https://github.com/dAppCore/go-io/pull/2"}` assert.Equal(t, "https://github.com/dAppCore/go-io/pull/2", extractJSONField(json, "url")) } -func TestExtractJSONField_Good_PrettyPrinted(t *testing.T) { +func TestMirror_ExtractJSONField_Good_PrettyPrinted(t *testing.T) { json := "[\n {\n \"url\": \"https://github.com/dAppCore/go-io/pull/3\"\n }\n]" assert.Equal(t, "https://github.com/dAppCore/go-io/pull/3", extractJSONField(json, "url")) } -func TestExtractJSONField_Bad_Missing(t *testing.T) { +func TestMirror_ExtractJSONField_Bad_Missing(t *testing.T) { assert.Equal(t, "", extractJSONField(`{"name":"test"}`, "url")) assert.Equal(t, "", extractJSONField("", "url")) } -func TestValidPlanStatus_Good(t *testing.T) { +func TestPlan_ValidPlanStatus_Good(t *testing.T) { assert.True(t, validPlanStatus("draft")) assert.True(t, validPlanStatus("in_progress")) assert.True(t, validPlanStatus("draft")) } -func TestValidPlanStatus_Bad(t *testing.T) { +func TestPlan_ValidPlanStatus_Bad(t *testing.T) { assert.False(t, validPlanStatus("invalid")) assert.False(t, validPlanStatus("")) } -func TestGeneratePlanID_Good(t *testing.T) { +func TestPlan_GeneratePlanID_Good(t *testing.T) { id := generatePlanID("Fix the login bug in auth service") assert.True(t, len(id) > 0) assert.True(t, strings.Contains(id, "fix-the-login-bug")) diff --git a/pkg/agentic/plan_crud_test.go b/pkg/agentic/plan_crud_test.go index ac9c499..83021c3 100644 --- a/pkg/agentic/plan_crud_test.go +++ b/pkg/agentic/plan_crud_test.go @@ -23,7 +23,7 @@ func newTestPrep(t *testing.T) *PrepSubsystem { // --- planCreate (MCP handler) --- -func TestPlanCreate_Good(t *testing.T) { +func TestPlan_PlanCreate_Good(t *testing.T) { dir := t.TempDir() t.Setenv("CORE_WORKSPACE", dir) @@ -48,7 +48,7 @@ func TestPlanCreate_Good(t *testing.T) { assert.NoError(t, statErr) } -func TestPlanCreate_Bad_MissingTitle(t *testing.T) { +func TestPlan_PlanCreate_Bad_MissingTitle(t *testing.T) { s := newTestPrep(t) _, _, err := s.planCreate(context.Background(), nil, PlanCreateInput{ Objective: "something", @@ -57,7 +57,7 @@ func TestPlanCreate_Bad_MissingTitle(t *testing.T) { assert.Contains(t, err.Error(), "title is required") } -func TestPlanCreate_Bad_MissingObjective(t *testing.T) { +func TestPlan_PlanCreate_Bad_MissingObjective(t *testing.T) { s := newTestPrep(t) _, _, err := s.planCreate(context.Background(), nil, PlanCreateInput{ Title: "My Plan", @@ -66,7 +66,7 @@ func TestPlanCreate_Bad_MissingObjective(t *testing.T) { assert.Contains(t, err.Error(), "objective is required") } -func TestPlanCreate_Good_DefaultPhaseStatus(t *testing.T) { +func TestPlan_PlanCreate_Good_DefaultPhaseStatus(t *testing.T) { dir := t.TempDir() t.Setenv("CORE_WORKSPACE", dir) @@ -88,7 +88,7 @@ func TestPlanCreate_Good_DefaultPhaseStatus(t *testing.T) { // --- planRead (MCP handler) --- -func TestPlanRead_Good(t *testing.T) { +func TestPlan_PlanRead_Good(t *testing.T) { dir := t.TempDir() t.Setenv("CORE_WORKSPACE", dir) @@ -107,14 +107,14 @@ func TestPlanRead_Good(t *testing.T) { assert.Equal(t, "draft", readOut.Plan.Status) } -func TestPlanRead_Bad_MissingID(t *testing.T) { +func TestPlan_PlanRead_Bad_MissingID(t *testing.T) { s := newTestPrep(t) _, _, err := s.planRead(context.Background(), nil, PlanReadInput{}) assert.Error(t, err) assert.Contains(t, err.Error(), "id is required") } -func TestPlanRead_Bad_NotFound(t *testing.T) { +func TestPlan_PlanRead_Bad_NotFound(t *testing.T) { dir := t.TempDir() t.Setenv("CORE_WORKSPACE", dir) @@ -126,7 +126,7 @@ func TestPlanRead_Bad_NotFound(t *testing.T) { // --- planUpdate (MCP handler) --- -func TestPlanUpdate_Good_Status(t *testing.T) { +func TestPlan_PlanUpdate_Good_Status(t *testing.T) { dir := t.TempDir() t.Setenv("CORE_WORKSPACE", dir) @@ -145,7 +145,7 @@ func TestPlanUpdate_Good_Status(t *testing.T) { assert.Equal(t, "ready", updateOut.Plan.Status) } -func TestPlanUpdate_Good_PartialUpdate(t *testing.T) { +func TestPlan_PlanUpdate_Good_PartialUpdate(t *testing.T) { dir := t.TempDir() t.Setenv("CORE_WORKSPACE", dir) @@ -168,7 +168,7 @@ func TestPlanUpdate_Good_PartialUpdate(t *testing.T) { assert.Equal(t, "codex", updateOut.Plan.Agent) } -func TestPlanUpdate_Good_AllStatusTransitions(t *testing.T) { +func TestPlan_PlanUpdate_Good_AllStatusTransitions(t *testing.T) { dir := t.TempDir() t.Setenv("CORE_WORKSPACE", dir) @@ -187,7 +187,7 @@ func TestPlanUpdate_Good_AllStatusTransitions(t *testing.T) { } } -func TestPlanUpdate_Bad_InvalidStatus(t *testing.T) { +func TestPlan_PlanUpdate_Bad_InvalidStatus(t *testing.T) { dir := t.TempDir() t.Setenv("CORE_WORKSPACE", dir) @@ -203,14 +203,14 @@ func TestPlanUpdate_Bad_InvalidStatus(t *testing.T) { assert.Contains(t, err.Error(), "invalid status") } -func TestPlanUpdate_Bad_MissingID(t *testing.T) { +func TestPlan_PlanUpdate_Bad_MissingID(t *testing.T) { s := newTestPrep(t) _, _, err := s.planUpdate(context.Background(), nil, PlanUpdateInput{Status: "ready"}) assert.Error(t, err) assert.Contains(t, err.Error(), "id is required") } -func TestPlanUpdate_Good_ReplacePhases(t *testing.T) { +func TestPlan_PlanUpdate_Good_ReplacePhases(t *testing.T) { dir := t.TempDir() t.Setenv("CORE_WORKSPACE", dir) @@ -232,7 +232,7 @@ func TestPlanUpdate_Good_ReplacePhases(t *testing.T) { // --- planDelete (MCP handler) --- -func TestPlanDelete_Good(t *testing.T) { +func TestPlan_PlanDelete_Good(t *testing.T) { dir := t.TempDir() t.Setenv("CORE_WORKSPACE", dir) @@ -250,14 +250,14 @@ func TestPlanDelete_Good(t *testing.T) { assert.True(t, os.IsNotExist(statErr)) } -func TestPlanDelete_Bad_MissingID(t *testing.T) { +func TestPlan_PlanDelete_Bad_MissingID(t *testing.T) { s := newTestPrep(t) _, _, err := s.planDelete(context.Background(), nil, PlanDeleteInput{}) assert.Error(t, err) assert.Contains(t, err.Error(), "id is required") } -func TestPlanDelete_Bad_NotFound(t *testing.T) { +func TestPlan_PlanDelete_Bad_NotFound(t *testing.T) { dir := t.TempDir() t.Setenv("CORE_WORKSPACE", dir) @@ -269,7 +269,7 @@ func TestPlanDelete_Bad_NotFound(t *testing.T) { // --- planList (MCP handler) --- -func TestPlanList_Good_Empty(t *testing.T) { +func TestPlan_PlanList_Good_Empty(t *testing.T) { dir := t.TempDir() t.Setenv("CORE_WORKSPACE", dir) @@ -280,7 +280,7 @@ func TestPlanList_Good_Empty(t *testing.T) { assert.Equal(t, 0, out.Count) } -func TestPlanList_Good_Multiple(t *testing.T) { +func TestPlan_PlanList_Good_Multiple(t *testing.T) { dir := t.TempDir() t.Setenv("CORE_WORKSPACE", dir) @@ -294,7 +294,7 @@ func TestPlanList_Good_Multiple(t *testing.T) { assert.Equal(t, 3, out.Count) } -func TestPlanList_Good_FilterByRepo(t *testing.T) { +func TestPlan_PlanList_Good_FilterByRepo(t *testing.T) { dir := t.TempDir() t.Setenv("CORE_WORKSPACE", dir) @@ -308,7 +308,7 @@ func TestPlanList_Good_FilterByRepo(t *testing.T) { assert.Equal(t, 2, out.Count) } -func TestPlanList_Good_FilterByStatus(t *testing.T) { +func TestPlan_PlanList_Good_FilterByStatus(t *testing.T) { dir := t.TempDir() t.Setenv("CORE_WORKSPACE", dir) @@ -323,7 +323,7 @@ func TestPlanList_Good_FilterByStatus(t *testing.T) { assert.Equal(t, "ready", out.Plans[0].Status) } -func TestPlanList_Good_IgnoresNonJSON(t *testing.T) { +func TestPlan_PlanList_Good_IgnoresNonJSON(t *testing.T) { dir := t.TempDir() t.Setenv("CORE_WORKSPACE", dir) @@ -341,12 +341,12 @@ func TestPlanList_Good_IgnoresNonJSON(t *testing.T) { // --- planPath edge cases --- -func TestPlanPath_Bad_PathTraversal(t *testing.T) { +func TestPlan_PlanPath_Bad_PathTraversal(t *testing.T) { p := planPath("/tmp/plans", "../../etc/passwd") assert.NotContains(t, p, "..") } -func TestPlanPath_Bad_Dot(t *testing.T) { +func TestPlan_PlanPath_Bad_Dot(t *testing.T) { assert.Contains(t, planPath("/tmp", "."), "invalid") assert.Contains(t, planPath("/tmp", ".."), "invalid") assert.Contains(t, planPath("/tmp", ""), "invalid") diff --git a/pkg/agentic/plan_logic_test.go b/pkg/agentic/plan_logic_test.go index fe6179b..6a2dbd1 100644 --- a/pkg/agentic/plan_logic_test.go +++ b/pkg/agentic/plan_logic_test.go @@ -13,37 +13,37 @@ import ( // --- planPath --- -func TestPlanPath_Good_BasicFormat(t *testing.T) { +func TestPlan_PlanPath_Good_BasicFormat(t *testing.T) { result := planPath("/tmp/plans", "my-plan-abc123") assert.Equal(t, "/tmp/plans/my-plan-abc123.json", result) } -func TestPlanPath_Good_NestedIDStripped(t *testing.T) { +func TestPlan_PlanPath_Good_NestedIDStripped(t *testing.T) { // PathBase strips directory component — prevents path traversal result := planPath("/plans", "../../../etc/passwd") assert.Equal(t, "/plans/passwd.json", result) } -func TestPlanPath_Good_SimpleID(t *testing.T) { +func TestPlan_PlanPath_Good_SimpleID(t *testing.T) { assert.Equal(t, "/data/test.json", planPath("/data", "test")) } -func TestPlanPath_Good_SlugWithDashes(t *testing.T) { +func TestPlan_PlanPath_Good_SlugWithDashes(t *testing.T) { assert.Equal(t, "/root/migrate-core-abc123.json", planPath("/root", "migrate-core-abc123")) } -func TestPlanPath_Bad_DotID(t *testing.T) { +func TestPlan_PlanPath_Bad_DotID(t *testing.T) { // "." is sanitised to "invalid" to prevent exploiting the root directory result := planPath("/plans", ".") assert.Equal(t, "/plans/invalid.json", result) } -func TestPlanPath_Bad_DoubleDotID(t *testing.T) { +func TestPlan_PlanPath_Bad_DoubleDotID(t *testing.T) { result := planPath("/plans", "..") assert.Equal(t, "/plans/invalid.json", result) } -func TestPlanPath_Bad_EmptyID(t *testing.T) { +func TestPlan_PlanPath_Bad_EmptyID(t *testing.T) { result := planPath("/plans", "") assert.Equal(t, "/plans/invalid.json", result) } @@ -112,13 +112,13 @@ func TestReadWritePlan_Good_WithPhases(t *testing.T) { assert.Equal(t, "pending", read.Phases[2].Status) } -func TestReadPlan_Bad_MissingFile(t *testing.T) { +func TestPlan_ReadPlan_Bad_MissingFile(t *testing.T) { dir := t.TempDir() _, err := readPlan(dir, "nonexistent-plan") assert.Error(t, err) } -func TestReadPlan_Bad_CorruptJSON(t *testing.T) { +func TestPlan_ReadPlan_Bad_CorruptJSON(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "bad.json"), `{broken`).OK) @@ -126,7 +126,7 @@ func TestReadPlan_Bad_CorruptJSON(t *testing.T) { assert.Error(t, err) } -func TestWritePlan_Good_CreatesNestedDir(t *testing.T) { +func TestPlan_WritePlan_Good_CreatesNestedDir(t *testing.T) { base := t.TempDir() nested := filepath.Join(base, "deep", "nested", "plans") @@ -143,7 +143,7 @@ func TestWritePlan_Good_CreatesNestedDir(t *testing.T) { assert.True(t, fs.IsFile(path)) } -func TestWritePlan_Good_OverwriteExistingLogic(t *testing.T) { +func TestPlan_WritePlan_Good_OverwriteExistingLogic(t *testing.T) { dir := t.TempDir() plan := &Plan{ @@ -166,7 +166,7 @@ func TestWritePlan_Good_OverwriteExistingLogic(t *testing.T) { assert.Equal(t, "approved", read.Status) } -func TestReadPlan_Ugly_EmptyFileLogic(t *testing.T) { +func TestPlan_ReadPlan_Ugly_EmptyFileLogic(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "empty.json"), "").OK) diff --git a/pkg/agentic/plan_test.go b/pkg/agentic/plan_test.go index 1440c24..9f574c1 100644 --- a/pkg/agentic/plan_test.go +++ b/pkg/agentic/plan_test.go @@ -11,12 +11,12 @@ import ( "github.com/stretchr/testify/require" ) -func TestPlanPath_Good(t *testing.T) { +func TestPlan_PlanPath_Good(t *testing.T) { assert.Equal(t, "/tmp/plans/my-plan-abc123.json", planPath("/tmp/plans", "my-plan-abc123")) assert.Equal(t, "/data/test.json", planPath("/data", "test")) } -func TestWritePlan_Good(t *testing.T) { +func TestPlan_WritePlan_Good(t *testing.T) { dir := t.TempDir() plan := &Plan{ ID: "test-plan-abc123", @@ -33,7 +33,7 @@ func TestWritePlan_Good(t *testing.T) { assert.True(t, fs.IsFile(path)) } -func TestWritePlan_Good_CreatesDirectory(t *testing.T) { +func TestPlan_WritePlan_Good_CreatesDirectory(t *testing.T) { base := t.TempDir() dir := filepath.Join(base, "nested", "plans") @@ -49,7 +49,7 @@ func TestWritePlan_Good_CreatesDirectory(t *testing.T) { assert.Contains(t, path, "nested-plan-abc123.json") } -func TestReadPlan_Good(t *testing.T) { +func TestPlan_ReadPlan_Good(t *testing.T) { dir := t.TempDir() original := &Plan{ ID: "read-test-abc123", @@ -87,13 +87,13 @@ func TestReadPlan_Good(t *testing.T) { assert.Equal(t, "claude:opus", read.Agent) } -func TestReadPlan_Bad_NotFound(t *testing.T) { +func TestPlan_ReadPlan_Bad_NotFound(t *testing.T) { dir := t.TempDir() _, err := readPlan(dir, "nonexistent-plan") assert.Error(t, err) } -func TestReadPlan_Bad_InvalidJSON(t *testing.T) { +func TestPlan_ReadPlan_Bad_InvalidJSON(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "bad-json.json"), "{broken").OK) @@ -134,7 +134,7 @@ func TestWriteReadPlan_Good_Roundtrip(t *testing.T) { assert.Equal(t, "Working on it", read.Phases[1].Notes) } -func TestGeneratePlanID_Good_Slugifies(t *testing.T) { +func TestPlan_GeneratePlanID_Good_Slugifies(t *testing.T) { id := generatePlanID("Add Unit Tests for Agentic") assert.True(t, strings.HasPrefix(id, "add-unit-tests-for-agentic"), "got: %s", id) // Should have random suffix @@ -142,7 +142,7 @@ func TestGeneratePlanID_Good_Slugifies(t *testing.T) { assert.True(t, len(parts) >= 5, "expected slug with random suffix, got: %s", id) } -func TestGeneratePlanID_Good_TruncatesLong(t *testing.T) { +func TestPlan_GeneratePlanID_Good_TruncatesLong(t *testing.T) { id := generatePlanID("This is a very long title that should be truncated to a reasonable length for file naming purposes") // Slug part (before random suffix) should be <= 30 chars lastDash := strings.LastIndex(id, "-") @@ -150,7 +150,7 @@ func TestGeneratePlanID_Good_TruncatesLong(t *testing.T) { assert.True(t, len(slug) <= 36, "slug too long: %s (%d chars)", slug, len(slug)) } -func TestGeneratePlanID_Good_HandlesSpecialChars(t *testing.T) { +func TestPlan_GeneratePlanID_Good_HandlesSpecialChars(t *testing.T) { id := generatePlanID("Fix bug #123: auth & session!") assert.True(t, strings.Contains(id, "fix-bug"), "got: %s", id) assert.NotContains(t, id, "#") @@ -158,27 +158,27 @@ func TestGeneratePlanID_Good_HandlesSpecialChars(t *testing.T) { assert.NotContains(t, id, "&") } -func TestGeneratePlanID_Good_Unique(t *testing.T) { +func TestPlan_GeneratePlanID_Good_Unique(t *testing.T) { id1 := generatePlanID("Same Title") id2 := generatePlanID("Same Title") assert.NotEqual(t, id1, id2, "IDs should differ due to random suffix") } -func TestValidPlanStatus_Good_AllValid(t *testing.T) { +func TestPlan_ValidPlanStatus_Good_AllValid(t *testing.T) { validStatuses := []string{"draft", "ready", "in_progress", "needs_verification", "verified", "approved"} for _, s := range validStatuses { assert.True(t, validPlanStatus(s), "expected %q to be valid", s) } } -func TestValidPlanStatus_Bad_Invalid(t *testing.T) { +func TestPlan_ValidPlanStatus_Bad_Invalid(t *testing.T) { invalidStatuses := []string{"", "running", "completed", "cancelled", "archived", "DRAFT", "Draft"} for _, s := range invalidStatuses { assert.False(t, validPlanStatus(s), "expected %q to be invalid", s) } } -func TestWritePlan_Good_OverwriteExisting(t *testing.T) { +func TestPlan_WritePlan_Good_OverwriteExisting(t *testing.T) { dir := t.TempDir() plan := &Plan{ @@ -202,7 +202,7 @@ func TestWritePlan_Good_OverwriteExisting(t *testing.T) { assert.Equal(t, "ready", read.Status) } -func TestReadPlan_Ugly_EmptyFile(t *testing.T) { +func TestPlan_ReadPlan_Ugly_EmptyFile(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "empty.json"), "").OK) diff --git a/pkg/agentic/pr_test.go b/pkg/agentic/pr_test.go index f4c53ab..318b8e6 100644 --- a/pkg/agentic/pr_test.go +++ b/pkg/agentic/pr_test.go @@ -59,7 +59,7 @@ func mockPRForgeServer(t *testing.T) *httptest.Server { // --- forgeCreatePR --- -func TestForgeCreatePR_Good_Success(t *testing.T) { +func TestPr_ForgeCreatePR_Good_Success(t *testing.T) { srv := mockPRForgeServer(t) s := &PrepSubsystem{ forge: forge.NewForge(srv.URL, "test-token"), @@ -81,7 +81,7 @@ func TestForgeCreatePR_Good_Success(t *testing.T) { assert.Contains(t, prURL, "pulls/12") } -func TestForgeCreatePR_Bad_ServerError(t *testing.T) { +func TestPr_ForgeCreatePR_Bad_ServerError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) json.NewEncoder(w).Encode(map[string]any{"message": "internal error"}) @@ -108,7 +108,7 @@ func TestForgeCreatePR_Bad_ServerError(t *testing.T) { // --- createPR (MCP tool) --- -func TestCreatePR_Bad_NoWorkspace(t *testing.T) { +func TestPr_CreatePR_Bad_NoWorkspace(t *testing.T) { s := &PrepSubsystem{ forgeToken: "test-token", backoff: make(map[string]time.Time), @@ -120,7 +120,7 @@ func TestCreatePR_Bad_NoWorkspace(t *testing.T) { assert.Contains(t, err.Error(), "workspace is required") } -func TestCreatePR_Bad_NoToken(t *testing.T) { +func TestPr_CreatePR_Bad_NoToken(t *testing.T) { s := &PrepSubsystem{ forgeToken: "", backoff: make(map[string]time.Time), @@ -134,7 +134,7 @@ func TestCreatePR_Bad_NoToken(t *testing.T) { assert.Contains(t, err.Error(), "no Forge token") } -func TestCreatePR_Bad_WorkspaceNotFound(t *testing.T) { +func TestPr_CreatePR_Bad_WorkspaceNotFound(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -151,7 +151,7 @@ func TestCreatePR_Bad_WorkspaceNotFound(t *testing.T) { assert.Contains(t, err.Error(), "workspace not found") } -func TestCreatePR_Good_DryRun(t *testing.T) { +func TestPr_CreatePR_Good_DryRun(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -190,7 +190,7 @@ func TestCreatePR_Good_DryRun(t *testing.T) { assert.Equal(t, "Fix the login bug", out.Title) } -func TestCreatePR_Good_CustomTitle(t *testing.T) { +func TestPr_CreatePR_Good_CustomTitle(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -228,7 +228,7 @@ func TestCreatePR_Good_CustomTitle(t *testing.T) { // --- listPRs --- -func TestListPRs_Bad_NoToken(t *testing.T) { +func TestPr_ListPRs_Bad_NoToken(t *testing.T) { s := &PrepSubsystem{ forgeToken: "", backoff: make(map[string]time.Time), @@ -242,7 +242,7 @@ func TestListPRs_Bad_NoToken(t *testing.T) { // --- commentOnIssue --- -func TestCommentOnIssue_Good_PostsComment(t *testing.T) { +func TestPr_CommentOnIssue_Good_PostsComment(t *testing.T) { commentPosted := false srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" { diff --git a/pkg/agentic/prep_extra_test.go b/pkg/agentic/prep_extra_test.go index 12506ac..6edaaad 100644 --- a/pkg/agentic/prep_extra_test.go +++ b/pkg/agentic/prep_extra_test.go @@ -18,7 +18,7 @@ import ( // --- Shutdown --- -func TestShutdown_Good(t *testing.T) { +func TestPrep_Shutdown_Good(t *testing.T) { s := &PrepSubsystem{ backoff: make(map[string]time.Time), failCount: make(map[string]int), @@ -29,14 +29,14 @@ func TestShutdown_Good(t *testing.T) { // --- Name --- -func TestName_Good(t *testing.T) { +func TestPrep_Name_Good(t *testing.T) { s := &PrepSubsystem{} assert.Equal(t, "agentic", s.Name()) } // --- findConsumersList --- -func TestFindConsumersList_Good_HasConsumers(t *testing.T) { +func TestPrep_FindConsumersList_Good_HasConsumers(t *testing.T) { dir := t.TempDir() // Create go.work @@ -76,7 +76,7 @@ use ( assert.Contains(t, list, "Breaking change risk") } -func TestFindConsumersList_Good_NoConsumers(t *testing.T) { +func TestPrep_FindConsumersList_Good_NoConsumers(t *testing.T) { dir := t.TempDir() goWork := `go 1.22 @@ -101,7 +101,7 @@ use ( assert.Empty(t, list) } -func TestFindConsumersList_Bad_NoGoWork(t *testing.T) { +func TestPrep_FindConsumersList_Bad_NoGoWork(t *testing.T) { s := &PrepSubsystem{ codePath: t.TempDir(), backoff: make(map[string]time.Time), @@ -115,7 +115,7 @@ func TestFindConsumersList_Bad_NoGoWork(t *testing.T) { // --- pullWikiContent --- -func TestPullWikiContent_Good_WithPages(t *testing.T) { +func TestPrep_PullWikiContent_Good_WithPages(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch { case r.URL.Path == "/api/v1/repos/core/go-io/wiki/pages": @@ -154,7 +154,7 @@ func TestPullWikiContent_Good_WithPages(t *testing.T) { assert.Contains(t, content, "### Architecture") } -func TestPullWikiContent_Good_NoPages(t *testing.T) { +func TestPrep_PullWikiContent_Good_NoPages(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode([]map[string]any{}) })) @@ -173,7 +173,7 @@ func TestPullWikiContent_Good_NoPages(t *testing.T) { // --- getIssueBody --- -func TestGetIssueBody_Good(t *testing.T) { +func TestPrep_GetIssueBody_Good(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(map[string]any{ "number": 15, @@ -194,7 +194,7 @@ func TestGetIssueBody_Good(t *testing.T) { assert.Contains(t, body, "tests are broken") } -func TestGetIssueBody_Bad_NotFound(t *testing.T) { +func TestPrep_GetIssueBody_Bad_NotFound(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(404) })) @@ -213,7 +213,7 @@ func TestGetIssueBody_Bad_NotFound(t *testing.T) { // --- buildPrompt --- -func TestBuildPrompt_Good_BasicFields(t *testing.T) { +func TestPrep_BuildPrompt_Good_BasicFields(t *testing.T) { dir := t.TempDir() // Create go.mod to detect language os.WriteFile(filepath.Join(dir, "go.mod"), []byte("module test\n\ngo 1.22\n"), 0o644) @@ -239,7 +239,7 @@ func TestBuildPrompt_Good_BasicFields(t *testing.T) { assert.Equal(t, 0, consumers) } -func TestBuildPrompt_Good_WithIssue(t *testing.T) { +func TestPrep_BuildPrompt_Good_WithIssue(t *testing.T) { dir := t.TempDir() srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -359,7 +359,7 @@ func TestPrep_BuildPrompt_Ugly(t *testing.T) { // --- runQA --- -func TestRunQA_Good_PHPNoComposer(t *testing.T) { +func TestDispatch_RunQA_Good_PHPNoComposer(t *testing.T) { dir := t.TempDir() repoDir := filepath.Join(dir, "repo") os.MkdirAll(repoDir, 0o755) diff --git a/pkg/agentic/prep_test.go b/pkg/agentic/prep_test.go index e51deac..dc0d06b 100644 --- a/pkg/agentic/prep_test.go +++ b/pkg/agentic/prep_test.go @@ -11,69 +11,69 @@ import ( "github.com/stretchr/testify/require" ) -func TestEnvOr_Good_EnvSet(t *testing.T) { +func TestPrep_EnvOr_Good_EnvSet(t *testing.T) { t.Setenv("TEST_ENVVAR_CUSTOM", "custom-value") assert.Equal(t, "custom-value", envOr("TEST_ENVVAR_CUSTOM", "default")) } -func TestEnvOr_Good_Fallback(t *testing.T) { +func TestPrep_EnvOr_Good_Fallback(t *testing.T) { t.Setenv("TEST_ENVVAR_MISSING", "") assert.Equal(t, "default-value", envOr("TEST_ENVVAR_MISSING", "default-value")) } -func TestEnvOr_Good_UnsetUsesFallback(t *testing.T) { +func TestPrep_EnvOr_Good_UnsetUsesFallback(t *testing.T) { t.Setenv("TEST_ENVVAR_TOTALLY_MISSING", "") assert.Equal(t, "fallback", envOr("TEST_ENVVAR_TOTALLY_MISSING", "fallback")) } -func TestDetectLanguage_Good_Go(t *testing.T) { +func TestPrep_DetectLanguage_Good_Go(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "go.mod"), "module test").OK) assert.Equal(t, "go", detectLanguage(dir)) } -func TestDetectLanguage_Good_PHP(t *testing.T) { +func TestPrep_DetectLanguage_Good_PHP(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "composer.json"), "{}").OK) assert.Equal(t, "php", detectLanguage(dir)) } -func TestDetectLanguage_Good_TypeScript(t *testing.T) { +func TestPrep_DetectLanguage_Good_TypeScript(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "package.json"), "{}").OK) assert.Equal(t, "ts", detectLanguage(dir)) } -func TestDetectLanguage_Good_Rust(t *testing.T) { +func TestPrep_DetectLanguage_Good_Rust(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "Cargo.toml"), "[package]").OK) assert.Equal(t, "rust", detectLanguage(dir)) } -func TestDetectLanguage_Good_Python(t *testing.T) { +func TestPrep_DetectLanguage_Good_Python(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "requirements.txt"), "flask").OK) assert.Equal(t, "py", detectLanguage(dir)) } -func TestDetectLanguage_Good_Cpp(t *testing.T) { +func TestPrep_DetectLanguage_Good_Cpp(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "CMakeLists.txt"), "cmake_minimum_required").OK) assert.Equal(t, "cpp", detectLanguage(dir)) } -func TestDetectLanguage_Good_Docker(t *testing.T) { +func TestPrep_DetectLanguage_Good_Docker(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "Dockerfile"), "FROM alpine").OK) assert.Equal(t, "docker", detectLanguage(dir)) } -func TestDetectLanguage_Good_DefaultsToGo(t *testing.T) { +func TestPrep_DetectLanguage_Good_DefaultsToGo(t *testing.T) { dir := t.TempDir() assert.Equal(t, "go", detectLanguage(dir)) } -func TestDetectBuildCmd_Good(t *testing.T) { +func TestPrep_DetectBuildCmd_Good(t *testing.T) { tests := []struct { file string content string @@ -96,12 +96,12 @@ func TestDetectBuildCmd_Good(t *testing.T) { } } -func TestDetectBuildCmd_Good_DefaultsToGo(t *testing.T) { +func TestPrep_DetectBuildCmd_Good_DefaultsToGo(t *testing.T) { dir := t.TempDir() assert.Equal(t, "go build ./...", detectBuildCmd(dir)) } -func TestDetectTestCmd_Good(t *testing.T) { +func TestPrep_DetectTestCmd_Good(t *testing.T) { tests := []struct { file string content string @@ -124,25 +124,25 @@ func TestDetectTestCmd_Good(t *testing.T) { } } -func TestDetectTestCmd_Good_DefaultsToGo(t *testing.T) { +func TestPrep_DetectTestCmd_Good_DefaultsToGo(t *testing.T) { dir := t.TempDir() assert.Equal(t, "go test ./...", detectTestCmd(dir)) } -func TestSanitiseBranchSlug_Good(t *testing.T) { +func TestSanitise_SanitiseBranchSlug_Good(t *testing.T) { assert.Equal(t, "fix-login-bug", sanitiseBranchSlug("Fix login bug!", 40)) assert.Equal(t, "trim-me", sanitiseBranchSlug("---Trim Me---", 40)) } -func TestSanitiseBranchSlug_Good_Truncates(t *testing.T) { +func TestSanitise_SanitiseBranchSlug_Good_Truncates(t *testing.T) { assert.Equal(t, "feature", sanitiseBranchSlug("feature--extra", 7)) } -func TestSanitiseFilename_Good(t *testing.T) { +func TestSanitise_SanitiseFilename_Good(t *testing.T) { assert.Equal(t, "Core---Agent-Notes", sanitiseFilename("Core / Agent:Notes")) } -func TestNewPrep_Good_Defaults(t *testing.T) { +func TestPrep_NewPrep_Good_Defaults(t *testing.T) { t.Setenv("FORGE_TOKEN", "") t.Setenv("GITEA_TOKEN", "") t.Setenv("CORE_BRAIN_KEY", "") @@ -157,7 +157,7 @@ func TestNewPrep_Good_Defaults(t *testing.T) { assert.NotNil(t, s.client) } -func TestNewPrep_Good_EnvOverrides(t *testing.T) { +func TestPrep_NewPrep_Good_EnvOverrides(t *testing.T) { t.Setenv("FORGE_URL", "https://custom-forge.example.com") t.Setenv("FORGE_TOKEN", "test-token") t.Setenv("CORE_BRAIN_URL", "https://custom-brain.example.com") @@ -173,7 +173,7 @@ func TestNewPrep_Good_EnvOverrides(t *testing.T) { assert.Equal(t, "/custom/code", s.codePath) } -func TestNewPrep_Good_GiteaTokenFallback(t *testing.T) { +func TestPrep_NewPrep_Good_GiteaTokenFallback(t *testing.T) { t.Setenv("FORGE_TOKEN", "") t.Setenv("GITEA_TOKEN", "gitea-fallback-token") @@ -186,7 +186,7 @@ func TestPrepSubsystem_Good_Name(t *testing.T) { assert.Equal(t, "agentic", s.Name()) } -func TestSetCore_Good(t *testing.T) { +func TestPrep_SetCore_Good(t *testing.T) { s := &PrepSubsystem{} assert.Nil(t, s.core) diff --git a/pkg/agentic/queue_extra_test.go b/pkg/agentic/queue_extra_test.go index 023726f..7ad41c0 100644 --- a/pkg/agentic/queue_extra_test.go +++ b/pkg/agentic/queue_extra_test.go @@ -78,7 +78,7 @@ concurrency: // --- delayForAgent (extended — sustained mode) --- -func TestDelayForAgent_Good_SustainedMode(t *testing.T) { +func TestQueue_DelayForAgent_Good_SustainedMode(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -106,7 +106,7 @@ rates: // --- countRunningByModel --- -func TestCountRunningByModel_Good_NoWorkspaces(t *testing.T) { +func TestQueue_CountRunningByModel_Good_NoWorkspaces(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) os.MkdirAll(filepath.Join(root, "workspace"), 0o755) @@ -120,7 +120,7 @@ func TestCountRunningByModel_Good_NoWorkspaces(t *testing.T) { // --- drainQueue / drainOne --- -func TestDrainQueue_Good_NoCoreFallsBackToMutex(t *testing.T) { +func TestQueue_DrainQueue_Good_NoCoreFallsBackToMutex(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) os.MkdirAll(filepath.Join(root, "workspace"), 0o755) @@ -134,7 +134,7 @@ func TestDrainQueue_Good_NoCoreFallsBackToMutex(t *testing.T) { assert.NotPanics(t, func() { s.drainQueue() }) } -func TestDrainOne_Good_NoWorkspaces(t *testing.T) { +func TestQueue_DrainOne_Good_NoWorkspaces(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) os.MkdirAll(filepath.Join(root, "workspace"), 0o755) @@ -147,7 +147,7 @@ func TestDrainOne_Good_NoWorkspaces(t *testing.T) { assert.False(t, s.drainOne()) } -func TestDrainOne_Good_SkipsNonQueued(t *testing.T) { +func TestQueue_DrainOne_Good_SkipsNonQueued(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) wsRoot := filepath.Join(root, "workspace") @@ -166,7 +166,7 @@ func TestDrainOne_Good_SkipsNonQueued(t *testing.T) { assert.False(t, s.drainOne()) } -func TestDrainOne_Good_SkipsBackedOffPool(t *testing.T) { +func TestQueue_DrainOne_Good_SkipsBackedOffPool(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) wsRoot := filepath.Join(root, "workspace") diff --git a/pkg/agentic/queue_logic_test.go b/pkg/agentic/queue_logic_test.go index c6ce08b..edf13b7 100644 --- a/pkg/agentic/queue_logic_test.go +++ b/pkg/agentic/queue_logic_test.go @@ -14,7 +14,7 @@ import ( // --- countRunningByModel --- -func TestCountRunningByModel_Good_Empty(t *testing.T) { +func TestQueue_CountRunningByModel_Good_Empty(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -22,7 +22,7 @@ func TestCountRunningByModel_Good_Empty(t *testing.T) { assert.Equal(t, 0, s.countRunningByModel("claude:opus")) } -func TestCountRunningByModel_Good_SkipsNonRunning(t *testing.T) { +func TestQueue_CountRunningByModel_Good_SkipsNonRunning(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -39,7 +39,7 @@ func TestCountRunningByModel_Good_SkipsNonRunning(t *testing.T) { assert.Equal(t, 0, s.countRunningByModel("codex:gpt-5.4")) } -func TestCountRunningByModel_Good_SkipsMismatchedModel(t *testing.T) { +func TestQueue_CountRunningByModel_Good_SkipsMismatchedModel(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -56,7 +56,7 @@ func TestCountRunningByModel_Good_SkipsMismatchedModel(t *testing.T) { assert.Equal(t, 0, s.countRunningByModel("gemini:pro")) } -func TestCountRunningByModel_Good_DeepLayout(t *testing.T) { +func TestQueue_CountRunningByModel_Good_DeepLayout(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -75,7 +75,7 @@ func TestCountRunningByModel_Good_DeepLayout(t *testing.T) { // --- drainQueue --- -func TestDrainQueue_Good_FrozenReturnsImmediately(t *testing.T) { +func TestQueue_DrainQueue_Good_FrozenReturnsImmediately(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -86,7 +86,7 @@ func TestDrainQueue_Good_FrozenReturnsImmediately(t *testing.T) { }) } -func TestDrainQueue_Good_EmptyWorkspace(t *testing.T) { +func TestQueue_DrainQueue_Good_EmptyWorkspace(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -99,7 +99,7 @@ func TestDrainQueue_Good_EmptyWorkspace(t *testing.T) { // --- Poke --- -func TestPoke_Good_NilChannel(t *testing.T) { +func TestRunner_Poke_Good_NilChannel(t *testing.T) { s := &PrepSubsystem{pokeCh: nil} // Must not panic when pokeCh is nil assert.NotPanics(t, func() { @@ -107,7 +107,7 @@ func TestPoke_Good_NilChannel(t *testing.T) { }) } -func TestPoke_Good_ChannelReceivesSignal(t *testing.T) { +func TestRunner_Poke_Good_ChannelReceivesSignal(t *testing.T) { s := &PrepSubsystem{} s.pokeCh = make(chan struct{}, 1) @@ -115,7 +115,7 @@ func TestPoke_Good_ChannelReceivesSignal(t *testing.T) { assert.Len(t, s.pokeCh, 1, "poke should enqueue one signal") } -func TestPoke_Good_NonBlockingWhenFull(t *testing.T) { +func TestRunner_Poke_Good_NonBlockingWhenFull(t *testing.T) { s := &PrepSubsystem{} s.pokeCh = make(chan struct{}, 1) // Pre-fill the channel @@ -130,7 +130,7 @@ func TestPoke_Good_NonBlockingWhenFull(t *testing.T) { // --- StartRunner --- -func TestStartRunner_Good_CreatesPokeCh(t *testing.T) { +func TestRunner_StartRunner_Good_CreatesPokeCh(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) t.Setenv("CORE_AGENT_DISPATCH", "") @@ -142,7 +142,7 @@ func TestStartRunner_Good_CreatesPokeCh(t *testing.T) { assert.NotNil(t, s.pokeCh, "StartRunner should initialise pokeCh") } -func TestStartRunner_Good_FrozenByDefault(t *testing.T) { +func TestRunner_StartRunner_Good_FrozenByDefault(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) t.Setenv("CORE_AGENT_DISPATCH", "") @@ -152,7 +152,7 @@ func TestStartRunner_Good_FrozenByDefault(t *testing.T) { assert.True(t, s.frozen, "queue should be frozen by default") } -func TestStartRunner_Good_AutoStartEnvVar(t *testing.T) { +func TestRunner_StartRunner_Good_AutoStartEnvVar(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) t.Setenv("CORE_AGENT_DISPATCH", "1") @@ -164,14 +164,14 @@ func TestStartRunner_Good_AutoStartEnvVar(t *testing.T) { // --- DefaultBranch --- -func TestDefaultBranch_Good_DefaultsToMain(t *testing.T) { +func TestPaths_DefaultBranch_Good_DefaultsToMain(t *testing.T) { // Non-git temp dir — git commands fail, fallback is "main" dir := t.TempDir() branch := DefaultBranch(dir) assert.Equal(t, "main", branch) } -func TestDefaultBranch_Good_RealGitRepo(t *testing.T) { +func TestPaths_DefaultBranch_Good_RealGitRepo(t *testing.T) { dir := t.TempDir() // Init a real git repo with a main branch require.NoError(t, runGitInit(dir)) @@ -183,12 +183,12 @@ func TestDefaultBranch_Good_RealGitRepo(t *testing.T) { // --- LocalFs --- -func TestLocalFs_Good_NonNil(t *testing.T) { +func TestPaths_LocalFs_Good_NonNil(t *testing.T) { f := LocalFs() assert.NotNil(t, f, "LocalFs should return a non-nil *core.Fs") } -func TestLocalFs_Good_CanRead(t *testing.T) { +func TestPaths_LocalFs_Good_CanRead(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "hello.txt") require.True(t, fs.Write(path, "hello").OK) diff --git a/pkg/agentic/queue_test.go b/pkg/agentic/queue_test.go index 3f54a37..0c29eb8 100644 --- a/pkg/agentic/queue_test.go +++ b/pkg/agentic/queue_test.go @@ -9,11 +9,11 @@ import ( "testing" ) -func TestBaseAgent_Ugly_Empty(t *testing.T) { +func TestQueue_BaseAgent_Ugly_Empty(t *testing.T) { assert.Equal(t, "", baseAgent("")) } -func TestBaseAgent_Ugly_MultipleColons(t *testing.T) { +func TestQueue_BaseAgent_Ugly_MultipleColons(t *testing.T) { // SplitN with N=2 should only split on first colon assert.Equal(t, "claude", baseAgent("claude:opus:extra")) } @@ -30,7 +30,7 @@ func TestDispatchConfig_Good_Defaults(t *testing.T) { assert.Equal(t, 3, cfg.Concurrency["gemini"].Total) } -func TestCanDispatchAgent_Good_NoConfig(t *testing.T) { +func TestQueue_CanDispatchAgent_Good_NoConfig(t *testing.T) { // With no running workspaces and default config, should be able to dispatch root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -40,7 +40,7 @@ func TestCanDispatchAgent_Good_NoConfig(t *testing.T) { assert.True(t, s.canDispatchAgent("gemini")) } -func TestCanDispatchAgent_Good_UnknownAgent(t *testing.T) { +func TestQueue_CanDispatchAgent_Good_UnknownAgent(t *testing.T) { // Unknown agent has no limit, so always allowed root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -50,7 +50,7 @@ func TestCanDispatchAgent_Good_UnknownAgent(t *testing.T) { assert.True(t, s.canDispatchAgent("unknown-agent")) } -func TestCountRunningByAgent_Good_EmptyWorkspace(t *testing.T) { +func TestQueue_CountRunningByAgent_Good_EmptyWorkspace(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) require.True(t, fs.EnsureDir(filepath.Join(root, "workspace")).OK) @@ -60,7 +60,7 @@ func TestCountRunningByAgent_Good_EmptyWorkspace(t *testing.T) { assert.Equal(t, 0, s.countRunningByAgent("claude")) } -func TestCountRunningByAgent_Good_NoRunning(t *testing.T) { +func TestQueue_CountRunningByAgent_Good_NoRunning(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -77,7 +77,7 @@ func TestCountRunningByAgent_Good_NoRunning(t *testing.T) { assert.Equal(t, 0, s.countRunningByAgent("gemini")) } -func TestDelayForAgent_Good_NoConfig(t *testing.T) { +func TestQueue_DelayForAgent_Good_NoConfig(t *testing.T) { // With no config, delay should be 0 t.Setenv("CORE_WORKSPACE", t.TempDir()) s := &PrepSubsystem{codePath: t.TempDir()} diff --git a/pkg/agentic/register_test.go b/pkg/agentic/register_test.go index ce06b1d..919d162 100644 --- a/pkg/agentic/register_test.go +++ b/pkg/agentic/register_test.go @@ -57,7 +57,7 @@ func TestRegister_Good_AgentsConfigLoaded(t *testing.T) { // --- OnStartup --- -func TestOnStartup_Good_CreatesPokeCh(t *testing.T) { +func TestPrep_OnStartup_Good_CreatesPokeCh(t *testing.T) { t.Setenv("CORE_WORKSPACE", t.TempDir()) t.Setenv("CORE_AGENT_DISPATCH", "") @@ -73,7 +73,7 @@ func TestOnStartup_Good_CreatesPokeCh(t *testing.T) { assert.NotNil(t, s.pokeCh, "OnStartup must initialise pokeCh via StartRunner") } -func TestOnStartup_Good_FrozenByDefault(t *testing.T) { +func TestPrep_OnStartup_Good_FrozenByDefault(t *testing.T) { t.Setenv("CORE_WORKSPACE", t.TempDir()) t.Setenv("CORE_AGENT_DISPATCH", "") @@ -85,7 +85,7 @@ func TestOnStartup_Good_FrozenByDefault(t *testing.T) { assert.True(t, s.frozen, "queue must be frozen after OnStartup without CORE_AGENT_DISPATCH=1") } -func TestOnStartup_Good_NoError(t *testing.T) { +func TestPrep_OnStartup_Good_NoError(t *testing.T) { t.Setenv("CORE_WORKSPACE", t.TempDir()) t.Setenv("CORE_AGENT_DISPATCH", "") @@ -99,7 +99,7 @@ func TestOnStartup_Good_NoError(t *testing.T) { // --- OnShutdown --- -func TestOnShutdown_Good_FreezesQueue(t *testing.T) { +func TestPrep_OnShutdown_Good_FreezesQueue(t *testing.T) { t.Setenv("CORE_WORKSPACE", t.TempDir()) s := &PrepSubsystem{frozen: false} @@ -108,7 +108,7 @@ func TestOnShutdown_Good_FreezesQueue(t *testing.T) { assert.True(t, s.frozen, "OnShutdown must set frozen=true") } -func TestOnShutdown_Good_AlreadyFrozen(t *testing.T) { +func TestPrep_OnShutdown_Good_AlreadyFrozen(t *testing.T) { // Calling OnShutdown twice must be idempotent s := &PrepSubsystem{frozen: true} err := s.OnShutdown(context.Background()) @@ -116,12 +116,12 @@ func TestOnShutdown_Good_AlreadyFrozen(t *testing.T) { assert.True(t, s.frozen) } -func TestOnShutdown_Good_NoError(t *testing.T) { +func TestPrep_OnShutdown_Good_NoError(t *testing.T) { s := &PrepSubsystem{} assert.NoError(t, s.OnShutdown(context.Background())) } -func TestOnShutdown_Ugly_NilCore(t *testing.T) { +func TestPrep_OnShutdown_Ugly_NilCore(t *testing.T) { // OnShutdown must not panic even if s.core is nil s := &PrepSubsystem{core: nil, frozen: false} assert.NotPanics(t, func() { diff --git a/pkg/agentic/remote_client_test.go b/pkg/agentic/remote_client_test.go index fd12dc2..08ede3a 100644 --- a/pkg/agentic/remote_client_test.go +++ b/pkg/agentic/remote_client_test.go @@ -16,7 +16,7 @@ import ( // --- mcpInitialize --- -func TestMcpInitialize_Good(t *testing.T) { +func TestRemoteClient_McpInitialize_Good(t *testing.T) { callCount := 0 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { callCount++ @@ -46,7 +46,7 @@ func TestMcpInitialize_Good(t *testing.T) { assert.Equal(t, 2, callCount, "should make init + notification requests") } -func TestMcpInitialize_Bad_ServerError(t *testing.T) { +func TestRemoteClient_McpInitialize_Bad_ServerError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) })) @@ -57,7 +57,7 @@ func TestMcpInitialize_Bad_ServerError(t *testing.T) { assert.Contains(t, err.Error(), "HTTP 500") } -func TestMcpInitialize_Bad_Unreachable(t *testing.T) { +func TestRemoteClient_McpInitialize_Bad_Unreachable(t *testing.T) { _, err := mcpInitialize(context.Background(), http.DefaultClient, "http://127.0.0.1:1", "") assert.Error(t, err) assert.Contains(t, err.Error(), "request failed") @@ -65,7 +65,7 @@ func TestMcpInitialize_Bad_Unreachable(t *testing.T) { // --- mcpCall --- -func TestMcpCall_Good(t *testing.T) { +func TestRemoteClient_McpCall_Good(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "Bearer mytoken", r.Header.Get("Authorization")) assert.Equal(t, "sess-123", r.Header.Get("Mcp-Session-Id")) @@ -81,7 +81,7 @@ func TestMcpCall_Good(t *testing.T) { assert.Contains(t, string(result), "hello") } -func TestMcpCall_Bad_HTTP500(t *testing.T) { +func TestRemoteClient_McpCall_Bad_HTTP500(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) })) @@ -92,7 +92,7 @@ func TestMcpCall_Bad_HTTP500(t *testing.T) { assert.Contains(t, err.Error(), "HTTP 500") } -func TestMcpCall_Bad_NoSSEData(t *testing.T) { +func TestRemoteClient_McpCall_Bad_NoSSEData(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/event-stream") fmt.Fprintf(w, "event: ping\n\n") // No data: line @@ -106,7 +106,7 @@ func TestMcpCall_Bad_NoSSEData(t *testing.T) { // --- setHeaders --- -func TestSetHeaders_Good_All(t *testing.T) { +func TestRemoteClient_SetHeaders_Good_All(t *testing.T) { req, _ := http.NewRequest("POST", "http://example.com", nil) setHeaders(req, "my-token", "my-session") @@ -116,7 +116,7 @@ func TestSetHeaders_Good_All(t *testing.T) { assert.Equal(t, "my-session", req.Header.Get("Mcp-Session-Id")) } -func TestSetHeaders_Good_NoToken(t *testing.T) { +func TestRemoteClient_SetHeaders_Good_NoToken(t *testing.T) { req, _ := http.NewRequest("POST", "http://example.com", nil) setHeaders(req, "", "") @@ -126,7 +126,7 @@ func TestSetHeaders_Good_NoToken(t *testing.T) { // --- readSSEData --- -func TestReadSSEData_Good(t *testing.T) { +func TestRemoteClient_ReadSSEData_Good(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/event-stream") fmt.Fprintf(w, "event: message\ndata: {\"key\":\"value\"}\n\n") @@ -142,7 +142,7 @@ func TestReadSSEData_Good(t *testing.T) { assert.Equal(t, `{"key":"value"}`, string(data)) } -func TestReadSSEData_Bad_NoData(t *testing.T) { +func TestRemoteClient_ReadSSEData_Bad_NoData(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "event: ping\n\n") })) @@ -159,7 +159,7 @@ func TestReadSSEData_Bad_NoData(t *testing.T) { // --- drainSSE --- -func TestDrainSSE_Good(t *testing.T) { +func TestRemoteClient_DrainSSE_Good(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "data: line1\ndata: line2\n\n") })) diff --git a/pkg/agentic/remote_test.go b/pkg/agentic/remote_test.go index b51ffa1..c3c4205 100644 --- a/pkg/agentic/remote_test.go +++ b/pkg/agentic/remote_test.go @@ -10,34 +10,34 @@ import ( // --- resolveHost (extended — base cases are in paths_test.go) --- -func TestResolveHost_Good_CaseInsensitive(t *testing.T) { +func TestRemote_ResolveHost_Good_CaseInsensitive(t *testing.T) { assert.Equal(t, "10.69.69.165:9101", resolveHost("Charon")) assert.Equal(t, "10.69.69.165:9101", resolveHost("CHARON")) assert.Equal(t, "127.0.0.1:9101", resolveHost("Cladius")) assert.Equal(t, "127.0.0.1:9101", resolveHost("LOCAL")) } -func TestResolveHost_Good_CustomHost(t *testing.T) { +func TestRemote_ResolveHost_Good_CustomHost(t *testing.T) { assert.Equal(t, "my-server:9101", resolveHost("my-server")) assert.Equal(t, "192.168.1.100:8080", resolveHost("192.168.1.100:8080")) } // --- remoteToken --- -func TestRemoteToken_Good_FromEnv(t *testing.T) { +func TestRemote_RemoteToken_Good_FromEnv(t *testing.T) { t.Setenv("AGENT_TOKEN_CHARON", "env-token-123") token := remoteToken("CHARON") assert.Equal(t, "env-token-123", token) } -func TestRemoteToken_Good_FallbackMCPAuth(t *testing.T) { +func TestRemote_RemoteToken_Good_FallbackMCPAuth(t *testing.T) { t.Setenv("AGENT_TOKEN_TOKENTEST", "") t.Setenv("MCP_AUTH_TOKEN", "mcp-fallback") token := remoteToken("tokentest") assert.Equal(t, "mcp-fallback", token) } -func TestRemoteToken_Good_EnvPrecedence(t *testing.T) { +func TestRemote_RemoteToken_Good_EnvPrecedence(t *testing.T) { t.Setenv("AGENT_TOKEN_PRIO", "specific-token") t.Setenv("MCP_AUTH_TOKEN", "generic-token") token := remoteToken("PRIO") diff --git a/pkg/agentic/render_plan_test.go b/pkg/agentic/render_plan_test.go index 0fa9de9..bc868bc 100644 --- a/pkg/agentic/render_plan_test.go +++ b/pkg/agentic/render_plan_test.go @@ -11,7 +11,7 @@ import ( // --- renderPlan --- -func TestRenderPlan_Good_BugFix(t *testing.T) { +func TestPrep_RenderPlan_Good_BugFix(t *testing.T) { s := &PrepSubsystem{ backoff: make(map[string]time.Time), failCount: make(map[string]int), @@ -26,7 +26,7 @@ func TestRenderPlan_Good_BugFix(t *testing.T) { assert.Contains(t, result, "Investigation") } -func TestRenderPlan_Good_WithVariables(t *testing.T) { +func TestPrep_RenderPlan_Good_WithVariables(t *testing.T) { s := &PrepSubsystem{ backoff: make(map[string]time.Time), failCount: make(map[string]int), @@ -42,7 +42,7 @@ func TestRenderPlan_Good_WithVariables(t *testing.T) { assert.Contains(t, result, "Fix login") } -func TestRenderPlan_Bad_UnknownTemplate(t *testing.T) { +func TestPrep_RenderPlan_Bad_UnknownTemplate(t *testing.T) { s := &PrepSubsystem{ backoff: make(map[string]time.Time), failCount: make(map[string]int), @@ -51,7 +51,7 @@ func TestRenderPlan_Bad_UnknownTemplate(t *testing.T) { assert.Empty(t, result) } -func TestRenderPlan_Good_NoTask(t *testing.T) { +func TestPrep_RenderPlan_Good_NoTask(t *testing.T) { s := &PrepSubsystem{ backoff: make(map[string]time.Time), failCount: make(map[string]int), @@ -63,7 +63,7 @@ func TestRenderPlan_Good_NoTask(t *testing.T) { assert.NotContains(t, result, "**Task:**") } -func TestRenderPlan_Good_NewFeature(t *testing.T) { +func TestPrep_RenderPlan_Good_NewFeature(t *testing.T) { s := &PrepSubsystem{ backoff: make(map[string]time.Time), failCount: make(map[string]int), diff --git a/pkg/agentic/review_queue_extra_test.go b/pkg/agentic/review_queue_extra_test.go index 9cbbdb2..1877733 100644 --- a/pkg/agentic/review_queue_extra_test.go +++ b/pkg/agentic/review_queue_extra_test.go @@ -17,7 +17,7 @@ import ( // --- buildReviewCommand --- -func TestBuildReviewCommand_Good_CodeRabbit(t *testing.T) { +func TestReviewQueue_BuildReviewCommand_Good_CodeRabbit(t *testing.T) { s := &PrepSubsystem{ backoff: make(map[string]time.Time), failCount: make(map[string]int), @@ -30,7 +30,7 @@ func TestBuildReviewCommand_Good_CodeRabbit(t *testing.T) { assert.Contains(t, cmd.Args, "github/main") } -func TestBuildReviewCommand_Good_Codex(t *testing.T) { +func TestReviewQueue_BuildReviewCommand_Good_Codex(t *testing.T) { s := &PrepSubsystem{ backoff: make(map[string]time.Time), failCount: make(map[string]int), @@ -42,7 +42,7 @@ func TestBuildReviewCommand_Good_Codex(t *testing.T) { assert.Equal(t, "/tmp/repo", cmd.Dir) } -func TestBuildReviewCommand_Good_DefaultReviewer(t *testing.T) { +func TestReviewQueue_BuildReviewCommand_Good_DefaultReviewer(t *testing.T) { s := &PrepSubsystem{ backoff: make(map[string]time.Time), failCount: make(map[string]int), @@ -86,7 +86,7 @@ func TestSaveLoadRateLimitState_Good_Roundtrip(t *testing.T) { // --- storeReviewOutput --- -func TestStoreReviewOutput_Good(t *testing.T) { +func TestReviewQueue_StoreReviewOutput_Good(t *testing.T) { // storeReviewOutput uses core.Env("DIR_HOME") so we can't fully control the path // but we can verify it doesn't panic s := &PrepSubsystem{ @@ -159,7 +159,7 @@ func TestStatus_Good_FilteredByStatus(t *testing.T) { // --- handlers helpers (resolveWorkspace, findWorkspaceByPR) --- -func TestResolveWorkspace_Good_Exists(t *testing.T) { +func TestHandlers_ResolveWorkspace_Good_Exists(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) wsRoot := filepath.Join(root, "workspace") @@ -172,7 +172,7 @@ func TestResolveWorkspace_Good_Exists(t *testing.T) { assert.Equal(t, ws, result) } -func TestResolveWorkspace_Bad_NotExists(t *testing.T) { +func TestHandlers_ResolveWorkspace_Bad_NotExists(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -180,7 +180,7 @@ func TestResolveWorkspace_Bad_NotExists(t *testing.T) { assert.Empty(t, result) } -func TestFindWorkspaceByPR_Good_Match(t *testing.T) { +func TestHandlers_FindWorkspaceByPR_Good_Match(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) wsRoot := filepath.Join(root, "workspace") @@ -195,7 +195,7 @@ func TestFindWorkspaceByPR_Good_Match(t *testing.T) { assert.Equal(t, ws, result) } -func TestFindWorkspaceByPR_Good_DeepLayout(t *testing.T) { +func TestHandlers_FindWorkspaceByPR_Good_DeepLayout(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) wsRoot := filepath.Join(root, "workspace") diff --git a/pkg/agentic/review_queue_test.go b/pkg/agentic/review_queue_test.go index 3b4ba9b..6c535eb 100644 --- a/pkg/agentic/review_queue_test.go +++ b/pkg/agentic/review_queue_test.go @@ -11,7 +11,7 @@ import ( // --- countFindings (extended beyond paths_test.go) --- -func TestCountFindings_Good_BulletFindings(t *testing.T) { +func TestReviewQueue_CountFindings_Good_BulletFindings(t *testing.T) { output := `Review: - Missing error check in handler.go:42 - Unused import in config.go @@ -19,18 +19,18 @@ func TestCountFindings_Good_BulletFindings(t *testing.T) { assert.Equal(t, 3, countFindings(output)) } -func TestCountFindings_Good_IssueKeyword(t *testing.T) { +func TestReviewQueue_CountFindings_Good_IssueKeyword(t *testing.T) { output := `Line 10: Issue: variable shadowing Line 25: Finding: unchecked return value` assert.Equal(t, 2, countFindings(output)) } -func TestCountFindings_Good_DefaultOneIfNotClean(t *testing.T) { +func TestReviewQueue_CountFindings_Good_DefaultOneIfNotClean(t *testing.T) { output := "Some output without markers but also not explicitly clean" assert.Equal(t, 1, countFindings(output)) } -func TestCountFindings_Good_MixedContent(t *testing.T) { +func TestReviewQueue_CountFindings_Good_MixedContent(t *testing.T) { output := `Summary of review: The code is generally well structured. - Missing nil check @@ -41,12 +41,12 @@ Some commentary here // --- parseRetryAfter (extended) --- -func TestParseRetryAfter_Good_SingleMinuteAndSeconds(t *testing.T) { +func TestReviewQueue_ParseRetryAfter_Good_SingleMinuteAndSeconds(t *testing.T) { d := parseRetryAfter("try after 1 minute and 30 seconds") assert.Equal(t, 1*time.Minute+30*time.Second, d) } -func TestParseRetryAfter_Bad_EmptyMessage(t *testing.T) { +func TestReviewQueue_ParseRetryAfter_Bad_EmptyMessage(t *testing.T) { d := parseRetryAfter("") assert.Equal(t, 5*time.Minute, d) } diff --git a/pkg/agentic/scan_test.go b/pkg/agentic/scan_test.go index 77e506a..feca3d9 100644 --- a/pkg/agentic/scan_test.go +++ b/pkg/agentic/scan_test.go @@ -184,7 +184,7 @@ func TestScan_Bad_NoToken(t *testing.T) { // --- listRepoIssues --- -func TestListRepoIssues_Good_ReturnsIssues(t *testing.T) { +func TestScan_ListRepoIssues_Good_ReturnsIssues(t *testing.T) { srv := mockScanServer(t) s := &PrepSubsystem{ forgeURL: srv.URL, @@ -202,7 +202,7 @@ func TestListRepoIssues_Good_ReturnsIssues(t *testing.T) { assert.Contains(t, issues[0].Labels, "agentic") } -func TestListRepoIssues_Good_EmptyResult(t *testing.T) { +func TestScan_ListRepoIssues_Good_EmptyResult(t *testing.T) { srv := mockScanServer(t) s := &PrepSubsystem{ forgeURL: srv.URL, @@ -217,7 +217,7 @@ func TestListRepoIssues_Good_EmptyResult(t *testing.T) { assert.Empty(t, issues) } -func TestListRepoIssues_Good_AssigneeExtracted(t *testing.T) { +func TestScan_ListRepoIssues_Good_AssigneeExtracted(t *testing.T) { srv := mockScanServer(t) s := &PrepSubsystem{ forgeURL: srv.URL, @@ -234,7 +234,7 @@ func TestListRepoIssues_Good_AssigneeExtracted(t *testing.T) { assert.Equal(t, "virgil", issues[1].Assignee) } -func TestListRepoIssues_Bad_ServerError(t *testing.T) { +func TestScan_ListRepoIssues_Bad_ServerError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) })) @@ -252,7 +252,7 @@ func TestListRepoIssues_Bad_ServerError(t *testing.T) { assert.Error(t, err) } -func TestListRepoIssues_Good_URLRewrite(t *testing.T) { +func TestScan_ListRepoIssues_Good_URLRewrite(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode([]map[string]any{ { diff --git a/pkg/agentic/status_extra_test.go b/pkg/agentic/status_extra_test.go index 8d20993..35b28b8 100644 --- a/pkg/agentic/status_extra_test.go +++ b/pkg/agentic/status_extra_test.go @@ -140,7 +140,7 @@ func TestStatus_Good_CorruptStatusFile(t *testing.T) { // --- shutdown tools --- -func TestDispatchStart_Good(t *testing.T) { +func TestShutdown_DispatchStart_Good(t *testing.T) { s := &PrepSubsystem{ frozen: true, pokeCh: make(chan struct{}, 1), @@ -155,7 +155,7 @@ func TestDispatchStart_Good(t *testing.T) { assert.Contains(t, out.Message, "started") } -func TestShutdownGraceful_Good(t *testing.T) { +func TestShutdown_ShutdownGraceful_Good(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -172,7 +172,7 @@ func TestShutdownGraceful_Good(t *testing.T) { assert.Contains(t, out.Message, "frozen") } -func TestShutdownNow_Good_EmptyWorkspace(t *testing.T) { +func TestShutdown_ShutdownNow_Good_EmptyWorkspace(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) require.True(t, fs.EnsureDir(filepath.Join(root, "workspace")).OK) @@ -190,7 +190,7 @@ func TestShutdownNow_Good_EmptyWorkspace(t *testing.T) { assert.Contains(t, out.Message, "killed 0") } -func TestShutdownNow_Good_ClearsQueued(t *testing.T) { +func TestShutdown_ShutdownNow_Good_ClearsQueued(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) wsRoot := filepath.Join(root, "workspace") @@ -227,7 +227,7 @@ func TestShutdownNow_Good_ClearsQueued(t *testing.T) { // --- brainRecall --- -func TestBrainRecall_Good_Success(t *testing.T) { +func TestPrep_BrainRecall_Good_Success(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "POST", r.Method) assert.Contains(t, r.URL.Path, "/v1/brain/recall") @@ -255,7 +255,7 @@ func TestBrainRecall_Good_Success(t *testing.T) { assert.Contains(t, result, "Use E() for errors") } -func TestBrainRecall_Good_NoMemories(t *testing.T) { +func TestPrep_BrainRecall_Good_NoMemories(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(map[string]any{ "memories": []map[string]any{}, @@ -276,7 +276,7 @@ func TestBrainRecall_Good_NoMemories(t *testing.T) { assert.Empty(t, result) } -func TestBrainRecall_Bad_NoBrainKey(t *testing.T) { +func TestPrep_BrainRecall_Bad_NoBrainKey(t *testing.T) { s := &PrepSubsystem{ brainKey: "", backoff: make(map[string]time.Time), @@ -288,7 +288,7 @@ func TestBrainRecall_Bad_NoBrainKey(t *testing.T) { assert.Empty(t, result) } -func TestBrainRecall_Bad_ServerError(t *testing.T) { +func TestPrep_BrainRecall_Bad_ServerError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) })) @@ -309,7 +309,7 @@ func TestBrainRecall_Bad_ServerError(t *testing.T) { // --- prepWorkspace --- -func TestPrepWorkspace_Bad_NoRepo(t *testing.T) { +func TestPrep_PrepWorkspace_Bad_NoRepo(t *testing.T) { s := &PrepSubsystem{ backoff: make(map[string]time.Time), failCount: make(map[string]int), @@ -320,7 +320,7 @@ func TestPrepWorkspace_Bad_NoRepo(t *testing.T) { assert.Contains(t, err.Error(), "repo is required") } -func TestPrepWorkspace_Bad_NoIdentifier(t *testing.T) { +func TestPrep_PrepWorkspace_Bad_NoIdentifier(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -337,7 +337,7 @@ func TestPrepWorkspace_Bad_NoIdentifier(t *testing.T) { assert.Contains(t, err.Error(), "one of issue, pr, branch, or tag is required") } -func TestPrepWorkspace_Bad_InvalidRepoName(t *testing.T) { +func TestPrep_PrepWorkspace_Bad_InvalidRepoName(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -357,7 +357,7 @@ func TestPrepWorkspace_Bad_InvalidRepoName(t *testing.T) { // --- listPRs --- -func TestListPRs_Good_SpecificRepo(t *testing.T) { +func TestPr_ListPRs_Good_SpecificRepo(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Return mock PRs json.NewEncoder(w).Encode([]map[string]any{ @@ -399,7 +399,7 @@ func TestListPRs_Good_SpecificRepo(t *testing.T) { // --- Poke --- -func TestPoke_Good_SendsSignal(t *testing.T) { +func TestRunner_Poke_Good_SendsSignal(t *testing.T) { s := &PrepSubsystem{ pokeCh: make(chan struct{}, 1), backoff: make(map[string]time.Time), @@ -416,7 +416,7 @@ func TestPoke_Good_SendsSignal(t *testing.T) { } } -func TestPoke_Good_NonBlocking(t *testing.T) { +func TestRunner_Poke_Good_NonBlocking(t *testing.T) { s := &PrepSubsystem{ pokeCh: make(chan struct{}, 1), backoff: make(map[string]time.Time), @@ -432,7 +432,7 @@ func TestPoke_Good_NonBlocking(t *testing.T) { }) } -func TestPoke_Bad_NilChannel(t *testing.T) { +func TestRunner_Poke_Bad_NilChannel(t *testing.T) { s := &PrepSubsystem{ pokeCh: nil, backoff: make(map[string]time.Time), @@ -504,7 +504,7 @@ func TestWriteReadStatus_Good_AllFields(t *testing.T) { // --- OnStartup / OnShutdown --- -func TestOnShutdown_Good(t *testing.T) { +func TestPrep_OnShutdown_Good(t *testing.T) { s := &PrepSubsystem{ frozen: false, backoff: make(map[string]time.Time), @@ -518,7 +518,7 @@ func TestOnShutdown_Good(t *testing.T) { // --- drainQueue --- -func TestDrainQueue_Good_FrozenDoesNothing(t *testing.T) { +func TestQueue_DrainQueue_Good_FrozenDoesNothing(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -536,7 +536,7 @@ func TestDrainQueue_Good_FrozenDoesNothing(t *testing.T) { // --- shutdownNow (Ugly — deep layout with queued status) --- -func TestShutdown_ShutdownNow_Ugly(t *testing.T) { +func TestPrep_Shutdown_ShutdownNow_Ugly(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) wsRoot := filepath.Join(root, "workspace") diff --git a/pkg/agentic/status_logic_test.go b/pkg/agentic/status_logic_test.go index a934941..0faf7d5 100644 --- a/pkg/agentic/status_logic_test.go +++ b/pkg/agentic/status_logic_test.go @@ -14,7 +14,7 @@ import ( // --- ReadStatus --- -func TestReadStatus_Good_AllFields(t *testing.T) { +func TestStatus_ReadStatus_Good_AllFields(t *testing.T) { dir := t.TempDir() now := time.Now().Truncate(time.Second) @@ -51,13 +51,13 @@ func TestReadStatus_Good_AllFields(t *testing.T) { assert.Equal(t, original.Runs, st.Runs) } -func TestReadStatus_Bad_MissingFile(t *testing.T) { +func TestStatus_ReadStatus_Bad_MissingFile(t *testing.T) { dir := t.TempDir() _, err := ReadStatus(dir) assert.Error(t, err, "missing status.json must return an error") } -func TestReadStatus_Bad_CorruptJSON(t *testing.T) { +func TestStatus_ReadStatus_Bad_CorruptJSON(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "status.json"), `{"status": "running", broken`).OK) @@ -65,7 +65,7 @@ func TestReadStatus_Bad_CorruptJSON(t *testing.T) { assert.Error(t, err, "corrupt JSON must return an error") } -func TestReadStatus_Bad_NullJSON(t *testing.T) { +func TestStatus_ReadStatus_Bad_NullJSON(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "status.json"), "null").OK) @@ -77,7 +77,7 @@ func TestReadStatus_Bad_NullJSON(t *testing.T) { // --- writeStatus --- -func TestWriteStatus_Good_WritesAndReadsBack(t *testing.T) { +func TestStatus_WriteStatus_Good_WritesAndReadsBack(t *testing.T) { dir := t.TempDir() st := &WorkspaceStatus{ Status: "queued", @@ -98,7 +98,7 @@ func TestWriteStatus_Good_WritesAndReadsBack(t *testing.T) { assert.Equal(t, "improve logging", read.Task) } -func TestWriteStatus_Good_SetsUpdatedAt(t *testing.T) { +func TestStatus_WriteStatus_Good_SetsUpdatedAt(t *testing.T) { dir := t.TempDir() before := time.Now().Add(-time.Millisecond) @@ -109,7 +109,7 @@ func TestWriteStatus_Good_SetsUpdatedAt(t *testing.T) { assert.True(t, st.UpdatedAt.After(before), "writeStatus must set UpdatedAt to a recent time") } -func TestWriteStatus_Good_Overwrites(t *testing.T) { +func TestStatus_WriteStatus_Good_Overwrites(t *testing.T) { dir := t.TempDir() require.NoError(t, writeStatus(dir, &WorkspaceStatus{Status: "running", Agent: "gemini"})) diff --git a/pkg/agentic/status_test.go b/pkg/agentic/status_test.go index c5539af..ea81d0c 100644 --- a/pkg/agentic/status_test.go +++ b/pkg/agentic/status_test.go @@ -11,7 +11,7 @@ import ( "time" ) -func TestWriteStatus_Good(t *testing.T) { +func TestStatus_WriteStatus_Good(t *testing.T) { dir := t.TempDir() status := &WorkspaceStatus{ Status: "running", @@ -43,7 +43,7 @@ func TestWriteStatus_Good(t *testing.T) { assert.False(t, read.UpdatedAt.IsZero(), "UpdatedAt should be set by writeStatus") } -func TestWriteStatus_Good_UpdatesTimestamp(t *testing.T) { +func TestStatus_WriteStatus_Good_UpdatesTimestamp(t *testing.T) { dir := t.TempDir() before := time.Now().Add(-time.Second) @@ -58,7 +58,7 @@ func TestWriteStatus_Good_UpdatesTimestamp(t *testing.T) { assert.True(t, status.UpdatedAt.After(before), "UpdatedAt should be after the start time") } -func TestReadStatus_Good(t *testing.T) { +func TestStatus_ReadStatus_Good(t *testing.T) { dir := t.TempDir() status := &WorkspaceStatus{ @@ -89,13 +89,13 @@ func TestReadStatus_Good(t *testing.T) { assert.Equal(t, "https://forge.lthn.ai/core/go-log/pulls/5", read.PRURL) } -func TestReadStatus_Bad_NoFile(t *testing.T) { +func TestStatus_ReadStatus_Bad_NoFile(t *testing.T) { dir := t.TempDir() _, err := ReadStatus(dir) assert.Error(t, err) } -func TestReadStatus_Bad_InvalidJSON(t *testing.T) { +func TestStatus_ReadStatus_Bad_InvalidJSON(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "status.json"), "not json{").OK) @@ -103,7 +103,7 @@ func TestReadStatus_Bad_InvalidJSON(t *testing.T) { assert.Error(t, err) } -func TestReadStatus_Good_BlockedWithQuestion(t *testing.T) { +func TestStatus_ReadStatus_Good_BlockedWithQuestion(t *testing.T) { dir := t.TempDir() status := &WorkspaceStatus{ @@ -157,7 +157,7 @@ func TestWriteReadStatus_Good_Roundtrip(t *testing.T) { assert.Equal(t, original.Runs, read.Runs) } -func TestWriteStatus_Good_OverwriteExisting(t *testing.T) { +func TestStatus_WriteStatus_Good_OverwriteExisting(t *testing.T) { dir := t.TempDir() first := &WorkspaceStatus{Status: "running", Agent: "gemini"} @@ -173,7 +173,7 @@ func TestWriteStatus_Good_OverwriteExisting(t *testing.T) { assert.Equal(t, "completed", read.Status) } -func TestReadStatus_Ugly_EmptyFile(t *testing.T) { +func TestStatus_ReadStatus_Ugly_EmptyFile(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "status.json"), "").OK) diff --git a/pkg/agentic/verify_extra_test.go b/pkg/agentic/verify_extra_test.go index 04d72f1..3a335a0 100644 --- a/pkg/agentic/verify_extra_test.go +++ b/pkg/agentic/verify_extra_test.go @@ -19,7 +19,7 @@ import ( // --- commentOnIssue --- -func TestCommentOnIssue_Good_PostsCommentOnPR(t *testing.T) { +func TestPr_CommentOnIssue_Good_PostsCommentOnPR(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "POST", r.Method) assert.Contains(t, r.URL.Path, "/issues/7/comments") @@ -46,7 +46,7 @@ func TestCommentOnIssue_Good_PostsCommentOnPR(t *testing.T) { // --- autoVerifyAndMerge integration (extended) --- -func TestAutoVerifyAndMerge_Good_FullPipeline(t *testing.T) { +func TestVerify_AutoVerifyAndMerge_Good_FullPipeline(t *testing.T) { // Mock Forge API for merge + comment mergeOK := false commented := false @@ -101,7 +101,7 @@ func TestAutoVerifyAndMerge_Good_FullPipeline(t *testing.T) { // --- attemptVerifyAndMerge --- -func TestAttemptVerifyAndMerge_Good_TestsPassMergeSucceeds(t *testing.T) { +func TestVerify_AttemptVerifyAndMerge_Good_TestsPassMergeSucceeds(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/api/v1/repos/core/test/pulls/1/merge" { w.WriteHeader(200) @@ -126,7 +126,7 @@ func TestAttemptVerifyAndMerge_Good_TestsPassMergeSucceeds(t *testing.T) { assert.Equal(t, mergeSuccess, result) } -func TestAttemptVerifyAndMerge_Bad_MergeFails(t *testing.T) { +func TestVerify_AttemptVerifyAndMerge_Bad_MergeFails(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/api/v1/repos/core/test/pulls/1/merge" { w.WriteHeader(409) diff --git a/pkg/agentic/verify_test.go b/pkg/agentic/verify_test.go index ca9a953..a10b682 100644 --- a/pkg/agentic/verify_test.go +++ b/pkg/agentic/verify_test.go @@ -18,7 +18,7 @@ import ( // --- forgeMergePR --- -func TestForgeMergePR_Good_Success(t *testing.T) { +func TestVerify_ForgeMergePR_Good_Success(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "POST", r.Method) assert.Contains(t, r.URL.Path, "/pulls/42/merge") @@ -45,7 +45,7 @@ func TestForgeMergePR_Good_Success(t *testing.T) { assert.NoError(t, err) } -func TestForgeMergePR_Good_204Response(t *testing.T) { +func TestVerify_ForgeMergePR_Good_204Response(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(204) // No Content — also valid success })) @@ -63,7 +63,7 @@ func TestForgeMergePR_Good_204Response(t *testing.T) { assert.NoError(t, err) } -func TestForgeMergePR_Bad_ConflictResponse(t *testing.T) { +func TestVerify_ForgeMergePR_Bad_ConflictResponse(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(409) json.NewEncoder(w).Encode(map[string]any{ @@ -86,7 +86,7 @@ func TestForgeMergePR_Bad_ConflictResponse(t *testing.T) { assert.Contains(t, err.Error(), "merge conflict") } -func TestForgeMergePR_Bad_ServerError(t *testing.T) { +func TestVerify_ForgeMergePR_Bad_ServerError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) json.NewEncoder(w).Encode(map[string]any{ @@ -108,7 +108,7 @@ func TestForgeMergePR_Bad_ServerError(t *testing.T) { assert.Contains(t, err.Error(), "500") } -func TestForgeMergePR_Bad_NetworkError(t *testing.T) { +func TestVerify_ForgeMergePR_Bad_NetworkError(t *testing.T) { srv := httptest.NewServer(http.NotFoundHandler()) srv.Close() // close immediately to cause connection error @@ -126,26 +126,26 @@ func TestForgeMergePR_Bad_NetworkError(t *testing.T) { // --- extractPRNumber (additional _Ugly cases) --- -func TestExtractPRNumber_Ugly_DoubleSlashEnd(t *testing.T) { +func TestVerify_ExtractPRNumber_Ugly_DoubleSlashEnd(t *testing.T) { assert.Equal(t, 0, extractPRNumber("https://forge.lthn.ai/core/go-io/pulls/42/")) } -func TestExtractPRNumber_Ugly_VeryLargeNumber(t *testing.T) { +func TestVerify_ExtractPRNumber_Ugly_VeryLargeNumber(t *testing.T) { assert.Equal(t, 999999, extractPRNumber("https://forge.lthn.ai/core/go-io/pulls/999999")) } -func TestExtractPRNumber_Ugly_NegativeNumber(t *testing.T) { +func TestVerify_ExtractPRNumber_Ugly_NegativeNumber(t *testing.T) { // atoi of "-5" is -5, parseInt wraps atoi assert.Equal(t, -5, extractPRNumber("https://forge.lthn.ai/core/go-io/pulls/-5")) } -func TestExtractPRNumber_Ugly_ZeroExplicit(t *testing.T) { +func TestVerify_ExtractPRNumber_Ugly_ZeroExplicit(t *testing.T) { assert.Equal(t, 0, extractPRNumber("https://forge.lthn.ai/core/go-io/pulls/0")) } // --- ensureLabel --- -func TestEnsureLabel_Good_CreatesLabel(t *testing.T) { +func TestVerify_EnsureLabel_Good_CreatesLabel(t *testing.T) { called := false srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "POST", r.Method) @@ -173,7 +173,7 @@ func TestEnsureLabel_Good_CreatesLabel(t *testing.T) { assert.True(t, called) } -func TestEnsureLabel_Bad_NetworkError(t *testing.T) { +func TestVerify_EnsureLabel_Bad_NetworkError(t *testing.T) { srv := httptest.NewServer(http.NotFoundHandler()) srv.Close() @@ -193,7 +193,7 @@ func TestEnsureLabel_Bad_NetworkError(t *testing.T) { // --- getLabelID --- -func TestGetLabelID_Good_Found(t *testing.T) { +func TestVerify_GetLabelID_Good_Found(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode([]map[string]any{ {"id": 10, "name": "agentic"}, @@ -214,7 +214,7 @@ func TestGetLabelID_Good_Found(t *testing.T) { assert.Equal(t, 20, id) } -func TestGetLabelID_Bad_NotFound(t *testing.T) { +func TestVerify_GetLabelID_Bad_NotFound(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode([]map[string]any{ {"id": 10, "name": "agentic"}, @@ -234,7 +234,7 @@ func TestGetLabelID_Bad_NotFound(t *testing.T) { assert.Equal(t, 0, id) } -func TestGetLabelID_Bad_NetworkError(t *testing.T) { +func TestVerify_GetLabelID_Bad_NetworkError(t *testing.T) { srv := httptest.NewServer(http.NotFoundHandler()) srv.Close() @@ -252,7 +252,7 @@ func TestGetLabelID_Bad_NetworkError(t *testing.T) { // --- runVerification --- -func TestRunVerification_Good_NoProjectFile(t *testing.T) { +func TestVerify_RunVerification_Good_NoProjectFile(t *testing.T) { dir := t.TempDir() // No go.mod, composer.json, or package.json s := &PrepSubsystem{ @@ -265,7 +265,7 @@ func TestRunVerification_Good_NoProjectFile(t *testing.T) { assert.Equal(t, "none", result.testCmd) } -func TestRunVerification_Good_GoProject(t *testing.T) { +func TestVerify_RunVerification_Good_GoProject(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "go.mod"), "module test").OK) @@ -279,7 +279,7 @@ func TestRunVerification_Good_GoProject(t *testing.T) { // It will fail because there's no real Go code, but we test the detection path } -func TestRunVerification_Good_PHPProject(t *testing.T) { +func TestVerify_RunVerification_Good_PHPProject(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "composer.json"), `{"require":{}}`).OK) @@ -293,7 +293,7 @@ func TestRunVerification_Good_PHPProject(t *testing.T) { assert.Contains(t, []string{"composer test", "vendor/bin/pest", "none"}, result.testCmd) } -func TestRunVerification_Good_NodeProject(t *testing.T) { +func TestVerify_RunVerification_Good_NodeProject(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "package.json"), `{"scripts":{"test":"echo ok"}}`).OK) @@ -306,7 +306,7 @@ func TestRunVerification_Good_NodeProject(t *testing.T) { assert.Equal(t, "npm test", result.testCmd) } -func TestRunVerification_Good_NodeNoTestScript(t *testing.T) { +func TestVerify_RunVerification_Good_NodeNoTestScript(t *testing.T) { dir := t.TempDir() require.True(t, fs.Write(filepath.Join(dir, "package.json"), `{"scripts":{}}`).OK) @@ -322,7 +322,7 @@ func TestRunVerification_Good_NodeNoTestScript(t *testing.T) { // --- fileExists --- -func TestFileExists_Good_Exists(t *testing.T) { +func TestVerify_FileExists_Good_Exists(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "test.txt") require.True(t, fs.Write(path, "hello").OK) @@ -330,18 +330,18 @@ func TestFileExists_Good_Exists(t *testing.T) { assert.True(t, fileExists(path)) } -func TestFileExists_Bad_NotExists(t *testing.T) { +func TestVerify_FileExists_Bad_NotExists(t *testing.T) { assert.False(t, fileExists("/nonexistent/path/file.txt")) } -func TestFileExists_Bad_IsDirectory(t *testing.T) { +func TestVerify_FileExists_Bad_IsDirectory(t *testing.T) { dir := t.TempDir() assert.False(t, fileExists(dir)) // directories are not files } // --- autoVerifyAndMerge --- -func TestAutoVerifyAndMerge_Bad_NoStatus(t *testing.T) { +func TestVerify_AutoVerifyAndMerge_Bad_NoStatus(t *testing.T) { dir := t.TempDir() s := &PrepSubsystem{ backoff: make(map[string]time.Time), @@ -353,7 +353,7 @@ func TestAutoVerifyAndMerge_Bad_NoStatus(t *testing.T) { }) } -func TestAutoVerifyAndMerge_Bad_NoPRURL(t *testing.T) { +func TestVerify_AutoVerifyAndMerge_Bad_NoPRURL(t *testing.T) { dir := t.TempDir() require.NoError(t, writeStatus(dir, &WorkspaceStatus{ Status: "completed", @@ -372,7 +372,7 @@ func TestAutoVerifyAndMerge_Bad_NoPRURL(t *testing.T) { }) } -func TestAutoVerifyAndMerge_Bad_EmptyRepo(t *testing.T) { +func TestVerify_AutoVerifyAndMerge_Bad_EmptyRepo(t *testing.T) { dir := t.TempDir() require.NoError(t, writeStatus(dir, &WorkspaceStatus{ Status: "completed", @@ -389,7 +389,7 @@ func TestAutoVerifyAndMerge_Bad_EmptyRepo(t *testing.T) { }) } -func TestAutoVerifyAndMerge_Bad_InvalidPRURL(t *testing.T) { +func TestVerify_AutoVerifyAndMerge_Bad_InvalidPRURL(t *testing.T) { dir := t.TempDir() require.NoError(t, writeStatus(dir, &WorkspaceStatus{ Status: "completed", @@ -411,7 +411,7 @@ func TestAutoVerifyAndMerge_Bad_InvalidPRURL(t *testing.T) { // --- flagForReview --- -func TestFlagForReview_Good_AddsLabel(t *testing.T) { +func TestVerify_FlagForReview_Good_AddsLabel(t *testing.T) { labelCalled := false commentCalled := false @@ -454,7 +454,7 @@ func TestFlagForReview_Good_AddsLabel(t *testing.T) { assert.True(t, commentCalled) } -func TestFlagForReview_Good_MergeConflictMessage(t *testing.T) { +func TestVerify_FlagForReview_Good_MergeConflictMessage(t *testing.T) { var commentBody string srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -488,23 +488,23 @@ func TestFlagForReview_Good_MergeConflictMessage(t *testing.T) { // --- truncate --- -func TestTruncate_Good_Short(t *testing.T) { +func TestAutoPr_Truncate_Good_Short(t *testing.T) { assert.Equal(t, "hello", truncate("hello", 10)) } -func TestTruncate_Good_Exact(t *testing.T) { +func TestAutoPr_Truncate_Good_Exact(t *testing.T) { assert.Equal(t, "hello", truncate("hello", 5)) } -func TestTruncate_Good_Long(t *testing.T) { +func TestAutoPr_Truncate_Good_Long(t *testing.T) { assert.Equal(t, "hel...", truncate("hello world", 3)) } -func TestTruncate_Bad_ZeroMax(t *testing.T) { +func TestAutoPr_Truncate_Bad_ZeroMax(t *testing.T) { assert.Equal(t, "...", truncate("hello", 0)) } -func TestTruncate_Ugly_EmptyString(t *testing.T) { +func TestAutoPr_Truncate_Ugly_EmptyString(t *testing.T) { assert.Equal(t, "", truncate("", 10)) } diff --git a/pkg/agentic/watch_test.go b/pkg/agentic/watch_test.go index 5988e14..4ff2eab 100644 --- a/pkg/agentic/watch_test.go +++ b/pkg/agentic/watch_test.go @@ -14,7 +14,7 @@ import ( // --- resolveWorkspaceDir --- -func TestResolveWorkspaceDir_Good_RelativeName(t *testing.T) { +func TestWatch_ResolveWorkspaceDir_Good_RelativeName(t *testing.T) { s := &PrepSubsystem{ backoff: make(map[string]time.Time), failCount: make(map[string]int), @@ -24,7 +24,7 @@ func TestResolveWorkspaceDir_Good_RelativeName(t *testing.T) { assert.True(t, filepath.IsAbs(dir)) } -func TestResolveWorkspaceDir_Good_AbsolutePath(t *testing.T) { +func TestWatch_ResolveWorkspaceDir_Good_AbsolutePath(t *testing.T) { s := &PrepSubsystem{ backoff: make(map[string]time.Time), failCount: make(map[string]int), @@ -35,7 +35,7 @@ func TestResolveWorkspaceDir_Good_AbsolutePath(t *testing.T) { // --- findActiveWorkspaces --- -func TestFindActiveWorkspaces_Good_WithActive(t *testing.T) { +func TestWatch_FindActiveWorkspaces_Good_WithActive(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root) @@ -69,7 +69,7 @@ func TestFindActiveWorkspaces_Good_WithActive(t *testing.T) { assert.NotContains(t, active, "ws-done") } -func TestFindActiveWorkspaces_Good_Empty(t *testing.T) { +func TestWatch_FindActiveWorkspaces_Good_Empty(t *testing.T) { root := t.TempDir() t.Setenv("CORE_WORKSPACE", root)