1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
from __future__ import annotations
import os
from inspect import Parameter, Signature, signature
from io import StringIO
from typing import Any
from unittest import mock
import pytest
from django.core.management import BaseCommand, CommandError
from django.core.management import call_command as base_call_command
from django.test import SimpleTestCase
from rich.console import Console
from django_rich.management import RichCommand
from tests.testapp.management.commands.example import Command as ExampleCommand
def strip_annotations(original: Signature) -> Signature:
return Signature(
parameters=[
param.replace(annotation=Parameter.empty)
for param in original.parameters.values()
]
)
class FakeTtyStringIO(StringIO):
def isatty(self) -> bool:
return True
def call_command(command: BaseCommand | str, *args: str, **kwargs: Any) -> None:
# Ensure rich uses colouring and consistent width
with mock.patch.dict(os.environ, TERM="", COLUMNS="80"):
base_call_command(command, *args, **kwargs)
class RichCommandTests(SimpleTestCase):
def test_init_signature(self):
rc_signature = strip_annotations(signature(RichCommand.__init__))
assert rc_signature == signature(BaseCommand.__init__)
def test_execute_signature(self):
rc_signature = strip_annotations(signature(RichCommand.execute))
assert rc_signature == signature(BaseCommand.execute)
def test_combined_color_flags_error(self):
with pytest.raises(CommandError) as excinfo:
call_command("example", "--no-color", "--force-color")
assert (
str(excinfo.value)
== "The --no-color and --force-color options can't be used together."
)
def test_output_non_tty(self):
stdout = StringIO()
call_command("example", stdout=stdout)
assert stdout.getvalue() == "Alert!\n"
def test_output_tty(self):
stdout = FakeTtyStringIO()
call_command("example", stdout=stdout)
assert stdout.getvalue() == "\x1b[1;31mAlert!\x1b[0m\n"
def test_output_tty_no_color(self):
stdout = FakeTtyStringIO()
call_command("example", "--no-color", stdout=stdout)
assert stdout.getvalue() == "Alert!\n"
def test_output_force_color(self):
stdout = StringIO()
call_command("example", "--force-color", stdout=stdout)
assert stdout.getvalue() == "\x1b[1;31mAlert!\x1b[0m\n"
def test_output_make_rich_console(self):
class TestCommand(ExampleCommand):
def make_rich_console(self, **kwargs: Any) -> Console:
return super().make_rich_console(
**kwargs, markup=False, highlight=False
)
stdout = FakeTtyStringIO()
call_command(TestCommand(), stdout=stdout)
assert stdout.getvalue() == "[bold red]Alert![/bold red]\n"
|