Skip to content

Fix testing related to the main module#327

Merged
dwash96 merged 23 commits intocecli-dev:v0.91.3from
johbo:fix-test-main
Dec 30, 2025
Merged

Fix testing related to the main module#327
dwash96 merged 23 commits intocecli-dev:v0.91.3from
johbo:fix-test-main

Conversation

@johbo
Copy link
Copy Markdown

@johbo johbo commented Dec 29, 2025

Tried to bring test_main.py back to life.

This PR includes needed changes to make the tests from test_main.py work again. My focus has been first on making them work and avoiding any additional refactoring in this step:

  • The test class is still a "unittest" style one. Converting it to the pytest patterns should be done in a future PR IMO.
  • A few test cases call async functions, to keep the changes minimal for now I did use asyncio.run. Once the tests are moved towards pytest's style, this can be simplified by using async test functions.
  • There is a bit of duplication around setting up the test cases, e.g. the mock coder. Think that will be reduced after moving the tests towards pytest's style.

johbo added 23 commits December 29, 2025 16:38
Added test_main_smoke.py with two smoke tests:
- test_main_async_executes: Tests async entry point
- test_main_executes: Tests sync entry point

These tests expose a bug where Path object is passed to
generate_search_path_list() which expects a string, causing
AttributeError when trying to call lstrip() on Path object.
Convert 76 async test methods to synchronous by:
- Removing 'async def' -> 'def' for test methods
- Removing 'await' from main() calls (main() handles asyncio.run internally)

3 tests remain async (marked with TODO comments) as they call
async helper functions (setup_git, check_gitignore, coder.allowed_to_edit)
and will need further refactoring.

This fixes the issue where async tests were never executing because
unittest.TestCase doesn't support async test methods.
The --yes flag is ambiguous as it matches both --yes-always and
--yes-always-commands. Update all test cases to use the explicit
--yes-always flag.
…ibute

Add autospec=True to 6 InputOutput mock tests to handle async methods
correctly. Configure 'pretty' attribute since autospec requires instance
attributes to be set manually.

Fixes 6 tests, bringing suite to 63 passed / 17 failed.
The create_env_file method was marked as async but only performs
synchronous file operations. This caused RuntimeWarning about
unawaited coroutines in tests that call it.

Fixes 2 tests, bringing suite to 65 passed / 15 failed.
Add mock_autosave_future() helper that returns AsyncMock()() to create
an awaitable coroutine for _autosave_future attribute. Apply fix to all
tests that patch Coder.create to avoid "object AsyncMock can't be used
in 'await' expression" errors.

For tests calling main() multiple times, create fresh coroutine before
each call since coroutines can only be awaited once.

Fixes 9 tests. Remaining 5 failures are unrelated to mock issues.
Configure mock_io.confirm_ask as AsyncMock to handle async confirm_ask
calls in check_gitignore. Fixes TypeError: object MagicMock can't be
used in 'await' expression.
Configure confirm_ask as AsyncMock on InputOutput mock return_value.
Commands.cmd_lint no longer exists, similar to cmd_add. Mark as xfail
for future refactoring.
Update test_return_coder and test_main_exit_with_git_command_not_found
to expect exit code 0 (success) instead of None. This aligns with the
graceful_exit() wrapper introduced in commit 7f813af which changed
main() to always return integer exit codes for proper shell integration.

Fixes final 2 test failures.
Windows uses USERPROFILE environment variable for Path.home() instead
of HOME. Use platform.system() to conditionally set the appropriate
environment variable for the platform.
- Convert test_setup_git from async def to def
- Convert test_check_gitignore from async def to def
- Convert test_argv_file_respects_git from async def to def
- Wrap async function calls with asyncio.run()
- Add asyncio import
- Remove @pytest.mark.skip decorators

All three tests now execute and pass (79 passed, 0 skipped, 2 xfailed)
…chitecture

- Remove @pytest.mark.xfail decorator
- Replace coder.commands.cmd_add() with asyncio.run(coder.commands.do_run())
- Add try/except SwitchCoder blocks (AddCommand raises this to signal refresh)
- Remove patch.object for confirm_ask (--yes-always handles this)
- Add SwitchCoder import

The add command was refactored from method-based to class-based in commit
82ba897. The test now uses the new Commands.do_run() API to execute
the AddCommand.execute() method through the CommandRegistry.

Test verifies gitignore behavior:
- Default: gitignored files rejected
- --add-gitignore-files: gitignored files accepted
- --no-add-gitignore-files: gitignored files rejected
- Update LintCommand to read CLI files from system_args instead of kwargs
- Add glob pattern expansion support for --lint flag
- Move expand_glob_patterns from main.py to utils.py to avoid circular imports
- Add tests for explicit files and glob patterns with --lint

This fixes the --lint flag after the command system refactoring (82ba897)
that moved commands to class-based architecture but didn't update callers.

Tests:
- test_lint_option: verifies --lint with no files (dirty file fallback)
- test_lint_option_with_explicit_files: verifies --lint file1.py file2.py
- test_lint_option_with_glob_pattern: verifies --lint *.py

All 83 tests pass.
CLI files were being resolved to absolute paths twice:
1. At line 26: str(Path(f).resolve())
2. At line 43: coder.abs_root_path(fname)

Now all file paths (CLI, in-chat, dirty) are resolved uniformly at line 43.
The check 'if not fnames and coder.repo' is redundant because we already
checked 'if not coder.repo' at line 27 and returned early. At line 35,
coder.repo is guaranteed to be truthy.
The 'root' parameter was defined but never used in the function body.
Verified that all 3 call sites (2 in main.py, 1 in lint.py) call it
without this parameter.
- Remove unused Path import from lint.py
- Remove unused glob import from main.py
- Remove unused pytest import from test_main.py
- Apply black formatting

All pre-commit hooks now pass.
@dwash96 dwash96 changed the base branch from main to v0.91.3 December 30, 2025 04:51
@dwash96 dwash96 merged commit 9e9d278 into cecli-dev:v0.91.3 Dec 30, 2025
8 checks passed
@dwash96 dwash96 mentioned this pull request Dec 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants