Skip to content

Commit 54650ea

Browse files
sypharpelme
authored andcommitted
Fixed #136 - fix the settings fixture for certain settings. (#324)
1 parent c3fffba commit 54650ea

File tree

3 files changed

+101
-15
lines changed

3 files changed

+101
-15
lines changed

pytest_django/fixtures.py

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -239,30 +239,45 @@ def rf():
239239
return RequestFactory()
240240

241241

242-
class MonkeyPatchWrapper(object):
243-
def __init__(self, monkeypatch, wrapped_object):
244-
super(MonkeyPatchWrapper, self).__setattr__('monkeypatch', monkeypatch)
245-
super(MonkeyPatchWrapper, self).__setattr__('wrapped_object',
246-
wrapped_object)
242+
class SettingsWrapper(object):
243+
_to_restore = []
247244

248-
def __getattr__(self, attr):
249-
return getattr(self.wrapped_object, attr)
245+
def __delattr__(self, attr):
246+
from django.test import override_settings
247+
override = override_settings()
248+
override.enable()
249+
from django.conf import settings
250+
delattr(settings, attr)
251+
252+
self._to_restore.append(override)
250253

251254
def __setattr__(self, attr, value):
252-
self.monkeypatch.setattr(self.wrapped_object, attr, value,
253-
raising=False)
255+
from django.test import override_settings
256+
override = override_settings(**{
257+
attr: value
258+
})
259+
override.enable()
260+
self._to_restore.append(override)
254261

255-
def __delattr__(self, attr):
256-
self.monkeypatch.delattr(self.wrapped_object, attr)
262+
def __getattr__(self, item):
263+
from django.conf import settings
264+
return getattr(settings, item)
257265

266+
def finalize(self):
267+
for override in reversed(self._to_restore):
268+
override.disable()
258269

259-
@pytest.fixture()
260-
def settings(monkeypatch):
270+
del self._to_restore[:]
271+
272+
273+
@pytest.yield_fixture()
274+
def settings():
261275
"""A Django settings object which restores changes after the testrun"""
262276
skip_if_no_django()
263277

264-
from django.conf import settings as django_settings
265-
return MonkeyPatchWrapper(monkeypatch, django_settings)
278+
wrapper = SettingsWrapper()
279+
yield wrapper
280+
wrapper.finalize()
266281

267282

268283
@pytest.fixture(scope='session')

tests/DBNAME_pytest_django_db

Whitespace-only changes.

tests/test_fixtures.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,77 @@ def test_deleted_again(self, settings):
8585
assert hasattr(settings, 'SECRET_KEY')
8686
assert hasattr(real_settings, 'SECRET_KEY')
8787

88+
def test_signals(self, settings):
89+
result = []
90+
91+
def assert_signal(signal, sender, setting, value, enter):
92+
result.append((setting, value, enter))
93+
94+
from django.test.signals import setting_changed
95+
setting_changed.connect(assert_signal)
96+
97+
result = []
98+
settings.SECRET_KEY = 'change 1'
99+
settings.SECRET_KEY = 'change 2'
100+
assert result == [
101+
('SECRET_KEY', 'change 1', True),
102+
('SECRET_KEY', 'change 2', True),
103+
]
104+
105+
result = []
106+
settings.FOOBAR = 'abc123'
107+
assert sorted(result) == [
108+
('FOOBAR', 'abc123', True),
109+
]
110+
111+
def test_modification_signal(self, django_testdir):
112+
django_testdir.create_test_module("""
113+
import pytest
114+
115+
from django.conf import settings
116+
from django.test.signals import setting_changed
117+
118+
119+
@pytest.fixture(autouse=True, scope='session')
120+
def settings_change_printer():
121+
def receiver(sender, **kwargs):
122+
fmt_dict = {'actual_value': getattr(settings, kwargs['setting'],
123+
'<<does not exist>>')}
124+
fmt_dict.update(kwargs)
125+
126+
print('Setting changed: '
127+
'enter=%(enter)s,setting=%(setting)s,'
128+
'value=%(value)s,actual_value=%(actual_value)s'
129+
% fmt_dict)
130+
131+
setting_changed.connect(receiver, weak=False)
132+
133+
134+
def test_set(settings):
135+
settings.SECRET_KEY = 'change 1'
136+
settings.SECRET_KEY = 'change 2'
137+
138+
139+
def test_set_non_existent(settings):
140+
settings.FOOBAR = 'abc123'
141+
""")
142+
143+
result = django_testdir.runpytest_subprocess('--tb=short', '-v', '-s')
144+
145+
# test_set
146+
result.stdout.fnmatch_lines([
147+
'*Setting changed: enter=True,setting=SECRET_KEY,value=change 1*',
148+
'*Setting changed: enter=True,setting=SECRET_KEY,value=change 2*',
149+
'*Setting changed: enter=False,setting=SECRET_KEY,value=change 1*',
150+
'*Setting changed: enter=False,setting=SECRET_KEY,value=foobar*',
151+
])
152+
153+
result.stdout.fnmatch_lines([
154+
'*Setting changed: enter=True,setting=FOOBAR,value=abc123*',
155+
('*Setting changed: enter=False,setting=FOOBAR,value=None,'
156+
'actual_value=<<does not exist>>*'),
157+
])
158+
88159

89160
class TestLiveServer:
90161
def test_url(self, live_server):

0 commit comments

Comments
 (0)