You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The developer's goal was to add test coverage to internal/bitbucket/host.go (~300 lines) which had zero tests, targeting six pure state-mapping helpers (normalizePRState, statusName, statusBucket, normalizePipelineUUID, pipelineUUIDFromStatusURL, failedPipelineUUIDs) that drive Bitbucket CI status interpretation and gate resolution. Requirements were to write table-driven tests with t.Run subtests focused on edge cases (malformed inputs, empty strings, unexpected values), follow the existing test conventions in internal/bitbucket/, and not modify host.go. Explicit constraints included branching off origin/main rather than local main, pushing to the e-jung/no-mistakes fork, opening a cross-repo PR to kunchenguid/no-mistakes with the specific title "test(bitbucket): add host.go state-mapping tests (300 lines, 0 covered)" and AI disclosure set to Human-reviewed, running go test ./internal/bitbucket/... -v, and not merging the PR. The developer also required staying within the worktree, reporting status via a status file, and leaving the merge decision to the maintainer.
What Changed
Added internal/bitbucket/host_test.go (390 lines) with table-driven tests covering the six pure state-mapping helpers in host.go: normalizePRState, statusName, statusBucket, normalizePipelineUUID, pipelineUUIDFromStatusURL, and failedPipelineUUIDs.
Tests target edge cases (malformed inputs, empty strings, unexpected values) across 89 subtests using t.Run, raising these helpers from 0% to covered.
No changes to host.go or production behavior; test-only addition following existing internal/bitbucket test conventions.
Risk Assessment
✅ Low: Test-only addition (no production code changed); all assertions trace correctly against the six pure helpers, conventions match existing tests, and go vet is clean.
Testing
Baseline go test -race ./... was already green. The added change is purely the new internal/bitbucket/host_test.go (390 lines), confirmed as the only diff vs base and with host.go untouched. go test ./internal/bitbucket/... -v passes all six new functions (TestNormalizePRState, TestStatusName, TestStatusBucket, TestNormalizePipelineUUID, TestPipelineUUIDFromStatusURL, TestFailedPipelineUUIDs) and every one of their 89 edge-case subtests (malformed/invalid-percent-escape URLs, empty/whitespace inputs, strings.Trim brace-cutset behavior, fragment-before-path URL parsing, nil/empty/dedup map results), and the race detector is clean. Coverage shows each of the six targeted helpers at exactly 100% (LatestStatuses transitively at 85.7%, not the target). Beyond pass/fail, three source mutations (forcing statusBucket's fail bucket to pass, dropping normalizePipelineUUID's ToLower, and reversing pipelineUUIDFromStatusURL's fragment/path order) were each caught by their corresponding test, proving the coverage is meaningful rather than vacuous; all mutations were reverted and host.go was restored to its committed state before finishing. No issues found; the user intent (add zero-previously-covered test coverage to host.go's six helpers, without modifying host.go) is satisfied.
Evidence: Verbose bitbucket test transcript (6 new fns, 89 subtests)
All 6 new test functions PASS with all subtests: TestNormalizePRState (18), TestStatusName (9), TestStatusBucket (18), TestNormalizePipelineUUID (16), TestPipelineUUIDFromStatusURL (13), TestFailedPipelineUUIDs (15). Final: PASS / ok github.com/kunchenguid/no-mistakes/internal/bitbucket
=== RUN TestNewClientFromEnvReadsAmbientEnvironment
--- PASS: TestNewClientFromEnvReadsAmbientEnvironment (0.00s)
=== RUN TestNewClientFromEnvPrefersExplicitEnvironment
--- PASS: TestNewClientFromEnvPrefersExplicitEnvironment (0.00s)
=== RUN TestParseRepoRefRejectsLookalikeHosts
=== RUN TestParseRepoRefRejectsLookalikeHosts/rejects_lookalike_host
=== RUN TestParseRepoRefRejectsLookalikeHosts/accepts_exact_host
=== RUN TestParseRepoRefRejectsLookalikeHosts/accepts_subdomain_host
--- PASS: TestParseRepoRefRejectsLookalikeHosts (0.00s)
=== RUN TestListPRStatusesFollowsPagination
--- PASS: TestListPRStatusesFollowsPagination (0.00s)
=== RUN TestListPRStatusesRejectsCrossOriginPagination
--- PASS: TestListPRStatusesRejectsCrossOriginPagination (0.00s)
=== RUN TestFindOpenPRBySourceAndDestinationBranchFiltersSourceRepo
--- PASS: TestFindOpenPRBySourceAndDestinationBranchFiltersSourceRepo (0.00s)
=== RUN TestListPipelinesByCommitFollowsPagination
--- PASS: TestListPipelinesByCommitFollowsPagination (0.00s)
=== RUN TestListPipelineStepsFollowsPagination
--- PASS: TestListPipelineStepsFollowsPagination (0.00s)
=== RUN TestGetStepLogCapsResponseToTail
--- PASS: TestGetStepLogCapsResponseToTail (0.00s)
=== RUN TestNormalizePRState
=== RUN TestNormalizePRState/open_canonical
=== RUN TestNormalizePRState/open_lowercase
=== RUN TestNormalizePRState/open_mixed_case
=== RUN TestNormalizePRState/open_with_surrounding_whitespace
=== RUN TestNormalizePRState/merged_canonical
=== RUN TestNormalizePRState/merged_lowercase
=== RUN TestNormalizePRState/merged_with_whitespace
=== RUN TestNormalizePRState/declined_canonical
=== RUN TestNormalizePRState/declined_lowercase
=== RUN TestNormalizePRState/closed_canonical
=== RUN TestNormalizePRState/closed_lowercase
=== RUN TestNormalizePRState/superseded_canonical
=== RUN TestNormalizePRState/superseded_lowercase
=== RUN TestNormalizePRState/unknown_state_passes_through_raw
=== RUN TestNormalizePRState/unknown_state_preserves_original_casing
=== RUN TestNormalizePRState/unknown_state_preserves_original_whitespace
=== RUN TestNormalizePRState/empty_string_stays_empty
=== RUN TestNormalizePRState/whitespace-only_with_no_recognized_token_returns_raw
--- PASS: TestNormalizePRState (0.00s)
=== RUN TestStatusName
=== RUN TestStatusName/name_present
=== RUN TestStatusName/name_takes_precedence_over_key
=== RUN TestStatusName/name_empty_falls_back_to_key
=== RUN TestStatusName/name_whitespace-only_falls_back_to_key
=== RUN TestStatusName/name_trimmed_when_returned
=== RUN TestStatusName/key_trimmed_when_used_as_fallback
=== RUN TestStatusName/both_empty_returns_empty
=== RUN TestStatusName/both_whitespace-only_returns_empty
=== RUN TestStatusName/neither_name_nor_key_set_but_state_populated_returns_empty
--- PASS: TestStatusName (0.00s)
=== RUN TestStatusBucket
=== RUN TestStatusBucket/successful_canonical
=== RUN TestStatusBucket/success_alias
=== RUN TestStatusBucket/successful_lowercase
=== RUN TestStatusBucket/successful_mixed_case
=== RUN TestStatusBucket/successful_with_whitespace
=== RUN TestStatusBucket/failed_canonical
=== RUN TestStatusBucket/failure_alias
=== RUN TestStatusBucket/error_alias
=== RUN TestStatusBucket/failed_lowercase
=== RUN TestStatusBucket/stopped_maps_to_cancel
=== RUN TestStatusBucket/stopped_lowercase
=== RUN TestStatusBucket/inprogress_no_underscore
=== RUN TestStatusBucket/in_progress_with_underscore
=== RUN TestStatusBucket/pending
=== RUN TestStatusBucket/inprogress_lowercase
=== RUN TestStatusBucket/unknown_returns_empty
=== RUN TestStatusBucket/empty_returns_empty
=== RUN TestStatusBucket/whitespace-only_returns_empty
--- PASS: TestStatusBucket (0.00s)
=== RUN TestNormalizePipelineUUID
=== RUN TestNormalizePipelineUUID/already_lowercase
=== RUN TestNormalizePipelineUUID/uppercase_lowered
=== RUN TestNormalizePipelineUUID/mixed_case_lowered
=== RUN TestNormalizePipelineUUID/with_braces_stripped
=== RUN TestNormalizePipelineUUID/with_braces_uppercase
=== RUN TestNormalizePipelineUUID/with_surrounding_spaces_trimmed
=== RUN TestNormalizePipelineUUID/spaces_and_braces_combined
=== RUN TestNormalizePipelineUUID/nested_braces_collapse
=== RUN TestNormalizePipelineUUID/only_leading_brace_stripped
=== RUN TestNormalizePipelineUUID/only_trailing_brace_stripped
=== RUN TestNormalizePipelineUUID/triple_trailing_braces
=== RUN TestNormalizePipelineUUID/interior_braces_preserved
=== RUN TestNormalizePipelineUUID/empty_returns_empty
=== RUN TestNormalizePipelineUUID/whitespace-only_returns_empty
=== RUN TestNormalizePipelineUUID/empty_braces_return_empty
=== RUN TestNormalizePipelineUUID/braces_with_whitespace_return_empty
--- PASS: TestNormalizePipelineUUID (0.00s)
=== RUN TestPipelineUUIDFromStatusURL
=== RUN TestPipelineUUIDFromStatusURL/valid_results_URL_with_braces
=== RUN TestPipelineUUIDFromStatusURL/UUID_without_braces
=== RUN TestPipelineUUIDFromStatusURL/uppercase_UUID_normalized_to_lowercase
=== RUN TestPipelineUUIDFromStatusURL/URL_with_query_string_strips_query
=== RUN TestPipelineUUIDFromStatusURL/URL_with_trailing_path_segment_stops_at_first_slash
=== RUN TestPipelineUUIDFromStatusURL/fragment_consulted_before_path
=== RUN TestPipelineUUIDFromStatusURL/last_results_segment_wins_when_duplicated
=== RUN TestPipelineUUIDFromStatusURL/URL_without_results_segment_returns_empty
=== RUN TestPipelineUUIDFromStatusURL/URL_whose_path_lacks_results_but_fragment_has_it_extracts_fragment_UUID
=== RUN TestPipelineUUIDFromStatusURL/empty_string_returns_empty
=== RUN TestPipelineUUIDFromStatusURL/whitespace-only_returns_empty
=== RUN TestPipelineUUIDFromStatusURL/plain_string_with_no_URL_structure_returns_empty
=== RUN TestPipelineUUIDFromStatusURL/malformed_URL_with_invalid_percent_escape_returns_empty
--- PASS: TestPipelineUUIDFromStatusURL (0.00s)
=== RUN TestFailedPipelineUUIDs
=== RUN TestFailedPipelineUUIDs/no_failing_names_returns_nil
=== RUN TestFailedPipelineUUIDs/empty_failing_names_slice_returns_nil
=== RUN TestFailedPipelineUUIDs/failing_names_all_whitespace_returns_nil
=== RUN TestFailedPipelineUUIDs/no_statuses_returns_nil
=== RUN TestFailedPipelineUUIDs/no_status_name_matches_a_failing_name_returns_nil
=== RUN TestFailedPipelineUUIDs/matching_status_with_no_results_URL_returns_nil
=== RUN TestFailedPipelineUUIDs/matching_status_with_empty_URL_returns_nil
=== RUN TestFailedPipelineUUIDs/single_match_extracts_UUID
=== RUN TestFailedPipelineUUIDs/multiple_distinct_failing_names_map_to_distinct_UUIDs
=== RUN TestFailedPipelineUUIDs/duplicate_UUIDs_collapse_into_a_single_target
=== RUN TestFailedPipelineUUIDs/only_the_requested_failing_names_contribute_UUIDs
=== RUN TestFailedPipelineUUIDs/failing_name_with_surrounding_whitespace_matches_trimmed_status_name
=== RUN TestFailedPipelineUUIDs/status_matched_by_key_when_name_is_empty
=== RUN TestFailedPipelineUUIDs/uppercase_UUIDs_in_URLs_are_normalized
=== RUN TestFailedPipelineUUIDs/LatestStatuses_dedup_happens_before_UUID_collection
--- PASS: TestFailedPipelineUUIDs (0.00s)
PASS
ok github.com/kunchenguid/no-mistakes/internal/bitbucket (cached)
go test ./internal/bitbucket/... -v (all 6 new test fns + existing bitbucket tests pass, 89 new subtests)
go test -race ./internal/bitbucket/... (clean)
go test ./internal/bitbucket/ -coverprofile (verified normalizePRState/statusName/statusBucket/normalizePipelineUUID/pipelineUUIDFromStatusURL/failedPipelineUUIDs each at 100%)
Thanks for the contribution, @e-jung! One process note on this repo: PRs need to be raised through no-mistakes (git push no-mistakes), which runs the review/test/lint/CI pipeline and stamps the required signature into the PR body. This PR is currently failing the "PR must be raised via no-mistakes" check because it wasn't raised that way.
If working from a fork was the blocker, that's fixed as of v1.30.0 (#306). Per CONTRIBUTING.md: point origin at this parent repo, run no-mistakes init --fork-url <your-fork-url>, then git push no-mistakes.
I won't be merging PRs that bypass the gate going forward, but I'd genuinely love to land your work once it's re-raised. Thanks for understanding! 🙏
Thanks @e-jung - merged! Really appreciate the contribution.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
The developer's goal was to add test coverage to internal/bitbucket/host.go (~300 lines) which had zero tests, targeting six pure state-mapping helpers (normalizePRState, statusName, statusBucket, normalizePipelineUUID, pipelineUUIDFromStatusURL, failedPipelineUUIDs) that drive Bitbucket CI status interpretation and gate resolution. Requirements were to write table-driven tests with t.Run subtests focused on edge cases (malformed inputs, empty strings, unexpected values), follow the existing test conventions in internal/bitbucket/, and not modify host.go. Explicit constraints included branching off origin/main rather than local main, pushing to the e-jung/no-mistakes fork, opening a cross-repo PR to kunchenguid/no-mistakes with the specific title "test(bitbucket): add host.go state-mapping tests (300 lines, 0 covered)" and AI disclosure set to Human-reviewed, running go test ./internal/bitbucket/... -v, and not merging the PR. The developer also required staying within the worktree, reporting status via a status file, and leaving the merge decision to the maintainer.
What Changed
internal/bitbucket/host_test.go(390 lines) with table-driven tests covering the six pure state-mapping helpers inhost.go:normalizePRState,statusName,statusBucket,normalizePipelineUUID,pipelineUUIDFromStatusURL, andfailedPipelineUUIDs.t.Run, raising these helpers from 0% to covered.host.goor production behavior; test-only addition following existinginternal/bitbuckettest conventions.Risk Assessment
✅ Low: Test-only addition (no production code changed); all assertions trace correctly against the six pure helpers, conventions match existing tests, and go vet is clean.
Testing
Baseline
go test -race ./...was already green. The added change is purely the new internal/bitbucket/host_test.go (390 lines), confirmed as the only diff vs base and with host.go untouched.go test ./internal/bitbucket/... -vpasses all six new functions (TestNormalizePRState, TestStatusName, TestStatusBucket, TestNormalizePipelineUUID, TestPipelineUUIDFromStatusURL, TestFailedPipelineUUIDs) and every one of their 89 edge-case subtests (malformed/invalid-percent-escape URLs, empty/whitespace inputs, strings.Trim brace-cutset behavior, fragment-before-path URL parsing, nil/empty/dedup map results), and the race detector is clean. Coverage shows each of the six targeted helpers at exactly 100% (LatestStatuses transitively at 85.7%, not the target). Beyond pass/fail, three source mutations (forcing statusBucket's fail bucket to pass, dropping normalizePipelineUUID's ToLower, and reversing pipelineUUIDFromStatusURL's fragment/path order) were each caught by their corresponding test, proving the coverage is meaningful rather than vacuous; all mutations were reverted and host.go was restored to its committed state before finishing. No issues found; the user intent (add zero-previously-covered test coverage to host.go's six helpers, without modifying host.go) is satisfied.Evidence: Verbose bitbucket test transcript (6 new fns, 89 subtests)
All 6 new test functions PASS with all subtests: TestNormalizePRState (18), TestStatusName (9), TestStatusBucket (18), TestNormalizePipelineUUID (16), TestPipelineUUIDFromStatusURL (13), TestFailedPipelineUUIDs (15). Final: PASS / ok github.com/kunchenguid/no-mistakes/internal/bitbucketEvidence: host.go per-function coverage (6 targeted helpers = 100%)
Evidence: Mutation-test evidence (tests catch regressions)
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ **Review** - passed
✅ No issues found.
✅ **Test** - passed
✅ No issues found.
go test -race ./...go test ./internal/bitbucket/... -v (all 6 new test fns + existing bitbucket tests pass, 89 new subtests)go test -race ./internal/bitbucket/... (clean)go test ./internal/bitbucket/ -coverprofile (verified normalizePRState/statusName/statusBucket/normalizePipelineUUID/pipelineUUIDFromStatusURL/failedPipelineUUIDs each at 100%)Mutation test: statusBucket FAILED-case -> pass (TestStatusBucket caught it), then revertedMutation test: normalizePipelineUUID drop ToLower (TestNormalizePipelineUUID caught it), then revertedMutation test: pipelineUUIDFromStatusURL swap fragment/path order (TestPipelineUUIDFromStatusURL caught it), then revertedgit diff 1432f3b..07a5c6f --stat (confirms only host_test.go added; host.go unchanged)✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.