test(core): stop output-format global leaking across tests - #93
Open
GregHolmes wants to merge 3 commits into
Open
test(core): stop output-format global leaking across tests#93GregHolmes wants to merge 3 commits into
GregHolmes wants to merge 3 commits into
Conversation
output_result reads the format from the process-global deepctl_core.output._output_config (via get_output_format), not from config.get(). But the five TestBaseCommand.test_output_result_* JSON tests only stubbed config.get.return_value = "json" — a no-op the code never reads — so they depended on an earlier CLI-invoking test having left the global on "json". They passed in the full suite by collection-order luck and failed in isolation (default format "default" → output_result returns early → _output_json / print_json never called). Fix both halves: - Patch deepctl_core.output._output_config in each JSON test (matching the yaml/table/csv tests) so they set the format the code actually reads. - Add an autouse fixture in packages/deepctl-core/tests/conftest.py that restores the pristine _output_config around every core test, so a format set by one test can no longer leak into the next. test_base.py in isolation: 5 failed -> 88 passed. Full core suite: 354 passed.
…ests
The 11 format-test patch dicts stood in for the process-global
deepctl_core.output._output_config but carried only 4 of its 5 keys
(agentic was missing). Safe on today's path — output_result ->
get_output_format reads only ["format"] and _output_json prints directly —
but other output.py helpers read _output_config["agentic"], so a future
refactor routing output through one of them would KeyError every 4-key-dict
test at once.
Add a shared _OUTPUT_CONFIG_DEFAULTS constant mirroring the real global's
full key set and spread it at each site ({**_OUTPUT_CONFIG_DEFAULTS,
"format": "json"}), removing both the drift risk and the duplication.
No behavior change: test_base.py 88 passed in isolation, full suite 976.
dg-coreylweathers
approved these changes
Aug 14, 2026
dg-coreylweathers
left a comment
There was a problem hiding this comment.
Approved — verified end-to-end, both rounds.
Re-ran the whole story locally rather than trusting the PR body:
- Reproduced the bug on
main:test_base.pyin isolation → 5 failed / 83 passed, exactly the fiveoutput_resultJSON tests, failing on the"default"early-return. Confirmed in source thatoutput_resultreadsget_output_format()→_output_config["format"], so the oldconfig.getstubs were no-ops as described. - On this branch: isolation 88 passed, core unit dir 354 passed,
ruff format --checkclean, no newruff checkfindings vs main. - The autouse reset fixture is correct: pristine snapshot taken at collection time before any test runs, in-place
clear()/update()composes cleanly with the tests'@patchswaps, no overlap with the root conftest. - f1469c1's
_OUTPUT_CONFIG_DEFAULTSspread resolves the missing-agentic-key shape drift across all 12 format tests, and the PR body now accounts for the ruff-format reflow.
Two non-gating notes for the record:
- Full suite here is 975 passed + 1 pre-existing unrelated failure:
test_file_info_modified_timestamp(deepctl-shared-utils) uses local-timefromtimestamp()and fails on any machine west of UTC — that's the 975-vs-976 gap between our machines. Deserves its own issue (fromtimestamp(ts, tz=timezone.utc)). - Core-scoped reset fixture accepted as-is; root-level version can follow if cross-package leakage ever shows up.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem
BaseCommand.output_resultreads the output format from the process-globaldeepctl_core.output._output_config(viaget_output_format()), not fromconfig.get(). But fiveTestBaseCommand.test_output_result_*JSON tests only stubbedconfig.get.return_value = "json"— a value the code never reads.As a result those tests depended on an earlier CLI-invoking test having left the global on
"json"(the CLI entrypointsrc/deepctl/main.pycallssetup_output(), which mutates the global and nothing resets it). They pass in the full suite by collection-order luck and fail in isolation:In isolation the format is its default
"default", sooutput_resultreturns early and_output_json/print_jsonis never called → the assertions fail.Fix (both halves)
@patch("deepctl_core.output._output_config", {...})— the same pattern the yaml/table/csv tests already use — instead of the no-opconfig.getstub. All 11 format patch sites now spread a shared_OUTPUT_CONFIG_DEFAULTSconstant ({**_OUTPUT_CONFIG_DEFAULTS, "format": "json"}) that mirrors the real global's full key set, so the stand-in can't drift from_output_config(previously the dicts omittedagentic).packages/deepctl-core/tests/conftest.pyrestores the pristine_output_configaround every core test, so a format set by one test can no longer bleed into the next.Half 1 makes the tests correct on their own; half 2 keeps the latent ordering bug from silently returning.
Verification
ruff / format clean (only test files touched). No
src/changes.Note on the diff
Includes ~90 lines of
ruff formatreflow inTestConfirmPromptGating/TestIsGuided(thewith patch(A), patch(B):blocks became parenthesizedwith ( … ):form, plus one line-wrap). All behavior-neutral formatter output, no logic change — called out here so it doesn't read as unexplained scope.Scope
Pre-existing core test hygiene — independent of #92. Reset fixture is intentionally core-scoped to limit blast radius; a root-level version (covering cross-package leakage) can follow if wanted.
🤖 Generated with Claude Code