File: unittest.py

package info (click to toggle)
python-django-constance 4.3.4-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 800 kB
  • sloc: python: 2,089; makefile: 25; javascript: 23; sh: 6
file content (89 lines) | stat: -rw-r--r-- 2,765 bytes parent folder | download
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
from functools import wraps

from django import VERSION as DJANGO_VERSION
from django.test import SimpleTestCase
from django.test.utils import override_settings

from constance import config

__all__ = ("override_config",)


class override_config(override_settings):
    """
    Decorator to modify constance setting for TestCase.

    Based on django.test.utils.override_settings.
    """

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.original_values = {}

    def __call__(self, test_func):
        """Modify the decorated function to override config values."""
        if isinstance(test_func, type):
            if not issubclass(test_func, SimpleTestCase):
                raise Exception("Only subclasses of Django SimpleTestCase can be decorated with override_config")
            return self.modify_test_case(test_func)

        @wraps(test_func)
        def inner(*args, **kwargs):
            with self:
                return test_func(*args, **kwargs)

        return inner

    def modify_test_case(self, test_case):
        """
        Override the config by modifying TestCase methods.

        This method follows the Django <= 1.6 method of overriding the
        _pre_setup and _post_teardown hooks rather than modifying the TestCase
        itself.
        """
        original_pre_setup = test_case._pre_setup
        original_post_teardown = test_case._post_teardown

        if DJANGO_VERSION < (5, 2):

            def _pre_setup(inner_self):
                self.enable()
                original_pre_setup(inner_self)

        else:

            @classmethod
            def _pre_setup(cls):
                # NOTE: Django 5.2 turned this as a classmethod
                # https://github.com/django/django/pull/18514/files
                self.enable()
                original_pre_setup()

        def _post_teardown(inner_self):
            original_post_teardown(inner_self)
            self.disable()

        test_case._pre_setup = _pre_setup
        test_case._post_teardown = _post_teardown

        return test_case

    def enable(self):
        """Store original config values and set overridden values."""
        # Store the original values to an instance variable
        for config_key in self.options:
            self.original_values[config_key] = getattr(config, config_key)

        # Update config with the overridden values
        self.unpack_values(self.options)

    def disable(self):
        """Set original values to the config."""
        self.unpack_values(self.original_values)

    @staticmethod
    def unpack_values(options):
        """Unpack values from the given dict to config."""
        for name, value in options.items():
            setattr(config, name, value)