Migrate prompt tests from InitAskStubber to huhtest.Responder

Overview

Migrate 11 test cases that currently use prompt.InitAskStubber() (which is incompatible with huh) to use the huhtest.Responder infrastructure instead.

Background

During the huh migration, we discovered that tests using prompt.InitAskStubber() are incompatible with huh prompts. The stubber was designed for survey prompts and doesn't intercept huh prompts.

As a temporary solution, we added skipPromptTest() helpers to skip these tests with clear TODO comments. Now we need to properly migrate them to use huhtest.Responder.

Current Status

11 tests are currently skipped across 5 test files:

1. internal/cmdutils/cmdutils_test.go - 6 tests

  • Test_PickMetadata - Tests metadata picker prompt
  • Test_UsersPrompt - Tests user selection prompt
  • Test_LabelsPromptAPIFail - Tests label prompt with API failure
  • Test_LabelsPromptPromptsFail - Tests label prompt with prompt failure
  • Test_LabelsPromptMultiSelect - Tests multi-select label prompt
  • Test_LabelsPromptAskQuestionWithInput - Tests label prompt with input

2. internal/commands/stack/create/stack_create_test.go - 1 test case

  • "empty string" test case (commented out, lines 56-64) - Tests stack creation when user provides empty title

3. internal/commands/mr/create/mr_create_test.go - 1 test

  • TestNewCmdCreate_TemplateFromCommitMessages - Tests MR creation with commit message template selection

4. internal/commands/mr/note/mr_note_create_test.go - 2 tests

  • Test_mrNoteCreate_prompt - Tests MR note creation with prompt
  • Test_mrNoteCreate_no_duplicate - Tests MR note duplicate detection with prompt

5. internal/commands/issuable/note/issuable_note_create_test.go - 1 test

  • Test_IssuableNoteCreate_prompt - Tests issue/incident note creation with prompt

Current Pattern (To Be Replaced)

// OLD: Using InitAskStubber (incompatible with huh)
as, teardown := prompt.InitAskStubber()
defer teardown()
as.StubOne("some user input")

output, err := runCommand(t, fakeHTTP, "args")

Target Pattern (Using huhtest.Responder)

The codebase already has huhtest.Responder infrastructure - see internal/commands/ci/ciutils/utils_test.go:197-241 for working examples.

// NEW: Using huhtest.Responder (compatible with huh)
responder := huhtest.NewResponder()
responder.AddResponse("Question prompt?", "user answer")
// or for selections:
responder.AddSelect("Select option:", "option1")
// or for multi-select:
responder.AddMultiSelect("Select multiple:", []string{"option1", "option2"})

ios, _, stdout, stderr := cmdtest.TestIOStreams(
    cmdtest.WithTestIOStreamsAsTTY(true),
    cmdtest.WithResponder(t, responder),
)

factory := cmdtest.NewTestFactory(ios, ...)
output, err := cmdtest.ExecuteCommand(cmd, args, stdout, stderr)

Implementation Strategy

Phase 1: Study Working Example (0.5 days)

  1. Read internal/commands/ci/ciutils/utils_test.go:197-241
  2. Understand how huhtest.Responder works with pipe setup
  3. Document the pattern for the team

Phase 2: Migrate Simple Tests First (1 day)

Start with the simplest test to establish the pattern:

  1. stack/create "empty string" test - Single input prompt

    • Uncomment the test case
    • Add huhtest.Responder with single response
    • Verify test passes
  2. mr/note tests - Single multiline input

    • Migrate Test_mrNoteCreate_prompt
    • Migrate Test_mrNoteCreate_no_duplicate

Phase 3: Migrate Complex Tests (2 days)

  1. cmdutils tests - Multiple tests with different prompt types

    • Test_PickMetadata - Multi-field form
    • Test_UsersPrompt - User selection
    • Test_LabelsPromptAPIFail - Label prompt with API mock
    • Test_LabelsPromptPromptsFail - Label prompt error handling
    • Test_LabelsPromptMultiSelect - Multi-select prompt
    • Test_LabelsPromptAskQuestionWithInput - Combined input/select
  2. mr/create test - Template selection prompt

    • TestNewCmdCreate_TemplateFromCommitMessages
  3. issuable/note test - Editor/multiline input

    • Test_IssuableNoteCreate_prompt

Phase 4: Cleanup (0.5 days)

Once all tests are migrated:

  1. Remove skipPromptTest() helper functions from all 5 test files
  2. Verify all tests pass: go test ./internal/cmdutils/... ./internal/commands/stack/create/... ./internal/commands/mr/... ./internal/commands/issuable/note/...
  3. Update HUH_MIGRATION_SUMMARY.md

Challenges and Solutions

Challenge 1: Pipe Setup Complexity

Problem: huhtest.Responder requires careful pipe setup with cmdtest.WithResponder(t, responder).

Solution:

  • Study existing working examples in ci/ciutils tests
  • Create a helper function if pattern is repetitive:
    func testIOStreamsWithResponder(t *testing.T, responder *huhtest.Responder) (*iostreams.IOStreams, *bytes.Buffer, *bytes.Buffer) {
        return cmdtest.TestIOStreams(
            cmdtest.WithTestIOStreamsAsTTY(true),
            cmdtest.WithResponder(t, responder),
        )
    }

Challenge 2: Matching Prompts

Problem: Responder needs exact prompt text to match against.

Solution:

  • Use MatchExact() for precise matching: responder.MatchExact()
  • Or use regex patterns for flexible matching (if huhtest supports it)
  • Debug with GLAB_DEBUG=1 go test -v to see actual prompts

Challenge 3: Multi-Field Forms

Problem: Tests with multiple sequential prompts need multiple responses in correct order.

Solution:

  • Add responses in the order prompts will appear:
    responder.AddResponse("Title:", "My Title")
    responder.AddResponse("Description:", "My Description")
  • Or use form-level responder if huhtest supports it

Challenge 4: Import Cycles

Problem: Some test files might have import cycle issues with cmdtest (like cmdutils_test.go did).

Solution:

  • Already resolved in cmdutils_test.go by creating local testIOStreams() helper
  • Reuse that pattern if needed

Success Criteria

  • All 11 tests migrated from InitAskStubber to huhtest.Responder
  • All tests pass: go test ./internal/cmdutils/... ./internal/commands/stack/create/... ./internal/commands/mr/... ./internal/commands/issuable/note/...
  • No tests skipped (all skipPromptTest() calls removed)
  • Tests properly verify prompt behavior
  • HUH_MIGRATION_SUMMARY.md updated

Testing

After each test migration:

# Run specific test
go test ./internal/cmdutils -run Test_PickMetadata -v

# Run all migrated tests
go test ./internal/cmdutils/... ./internal/commands/stack/create/... ./internal/commands/mr/... ./internal/commands/issuable/note/... -v

# Verify no tests are skipped
go test ./internal/cmdutils/... ./internal/commands/stack/create/... ./internal/commands/mr/... ./internal/commands/issuable/note/... | grep -c SKIP
# Should output: 0

Estimated Effort

4 days total

  • 0.5 day: Study huhtest.Responder examples and document pattern
  • 1 day: Migrate simple tests (3 tests)
  • 2 days: Migrate complex tests (8 tests)
  • 0.5 day: Cleanup, verify all pass, update docs

Dependencies

  • Depends on huh migration Phases 1-8 being complete
  • Unblocks removal of internal/prompt package (test-only)
  • Unblocks removal of survey dependency from go.mod
  • After this is complete, consider removing internal/prompt package entirely (currently only used by these tests)
  • This work is independent of the Editor() migration issue
Edited by Kai Armstrong