Skip to content

Commit

Permalink
fix #19
Browse files Browse the repository at this point in the history
  • Loading branch information
bckohan committed Nov 21, 2024
1 parent 9c3fb9b commit 97c91a1
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 15 deletions.
15 changes: 13 additions & 2 deletions django_typer/management/commands/shellcompletion.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,11 +599,22 @@ def get_completion() -> None:
)
call_fallback(fallback)

buffer = io.StringIO()
try:
get_completion()
with contextlib.redirect_stdout(buffer):
# typer's internal behavior is to print and exit, we need
# to intercept this workflow to do our post processing and
# honor the configured stdout
get_completion()

# leave this in, incase the interface changes to not exit
return buffer.getvalue() # pragma: no cover
except SystemExit:
completion_str = buffer.getvalue()
if completion_str:
return completion_str
if cmd_str:
return
return ""
raise

def django_fallback(self):
Expand Down
1 change: 1 addition & 0 deletions doc/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ v3.0.0 (202X-XX-XX)
* Implemented `Add showcase of commands using django-typer to docs <https://github.com/django-commons/django-typer/issues/142>`_
* Implemented `Add a @finalize decorator for functions to collect/operate on subroutine results. <https://github.com/django-commons/django-typer/issues/140>`_
* Fixed `Remove management imports in django_typer/__init__.py <https://github.com/django-commons/django-typer/issues/95>`_
* Fixed `shellcompletion complete should print to the command's stdout. <https://github.com/django-commons/django-typer/issues/19>`_

v2.4.0 (2024-11-07)
===================
Expand Down
5 changes: 2 additions & 3 deletions tests/shellcompletion/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,9 @@ def run_command_completion(self):
# and the completion on linux in bash specifically
self.assertTrue(re.match(r".*complet\s*ion.*", completions))
completions = self.get_completions(self.launch_script, " ")
self.assertIn("makemigrations", completions)
self.assertIn("migrate", completions)
self.assertIn("adapted", completions)
self.assertIn("help_precedence", completions)
self.assertIn("closepoll", completions)
self.assertIn("basic", completions)

def test_shell_complete(self):
with self.assertRaises(AssertionError):
Expand Down
16 changes: 6 additions & 10 deletions tests/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,12 +475,10 @@ def test_app_labels_completer(self):
)

shellcompletion = get_command("shellcompletion", ShellCompletion)
completions = shellcompletion.complete(
f"{self.app_labels_cmd} ", shell=Shells.zsh
)

stdout = StringIO()
with redirect_stdout(stdout):
shellcompletion.complete(f"{self.app_labels_cmd} ", shell=Shells.zsh)

completions = stdout.getvalue()
self.assertTrue('"contenttypes"' in completions)
self.assertTrue('"completers"' in completions)
self.assertTrue('"django_typer"' in completions)
Expand All @@ -489,11 +487,9 @@ def test_app_labels_completer(self):
self.assertTrue('"sessions"' in completions)
self.assertTrue('"messages"' in completions)

stdout.truncate(0)
stdout.seek(0)

with redirect_stdout(stdout):
shellcompletion.complete(f"{self.app_labels_cmd} a", shell=Shells.zsh)
completions = shellcompletion.complete(
f"{self.app_labels_cmd} a", shell=Shells.zsh
)

self.assertTrue('"admin"' in completions)
self.assertTrue('"auth"' in completions)
Expand Down
18 changes: 18 additions & 0 deletions tests/test_parser_completers.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,24 @@ def test_app_label_parser_idempotency(self):
poll_app = apps.get_app_config("tests_apps_examples_polls")
self.assertEqual(parse_app_label(poll_app), poll_app)

def test_shellcompletion_stdout(self):
from django_typer.management.commands.shellcompletion import (
Command as ShellCompletion,
)

shellcompletion = get_command("shellcompletion", ShellCompletion)
result = shellcompletion.complete("completion ")
self.assertTrue("test_app" in result)
self.assertTrue("tests_apps_util" in result)
self.assertTrue("django_typer" in result)

result2 = StringIO()
call_command("shellcompletion", "complete", "completion ", stdout=result2)
stdout_result = result2.getvalue().strip()
self.assertTrue("test_app" in stdout_result)
self.assertTrue("tests_apps_util" in stdout_result)
self.assertTrue("django_typer" in stdout_result)

def test_app_label_parser_completers(self):
from django.apps import apps

Expand Down

0 comments on commit 97c91a1

Please sign in to comment.