Skip to content

Instantly share code, notes, and snippets.

@lqc
Created November 4, 2010 23:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lqc/663367 to your computer and use it in GitHub Desktop.
Save lqc/663367 to your computer and use it in GitHub Desktop.
# from django.conf import settings
from functools import wraps
class _s:
def __init__(self, a=10, b=None):
self.a, self.b = a,b
def _override_settings(overrides):
_orig = {}
_missing = []
for k, v in overrides.iteritems():
try:
_orig[k] = getattr(settings, k)
except AttributeError:
_missing.append(k)
setattr(settings, k, v)
return _orig, _missing
def _restore_settings(original, missing):
for k, v in original.iteritems():
setattr(settings, k, v)
for key in missing:
delattr(settings, key)
class settings_altered(object):
def __init__(self, **overrides):
self.overrides = overrides
def __enter__(self):
self.original, self.missing = _override_settings(self.overrides)
def __exit__(self, exc_type, exc_value, tb):
_restore_settings(self.original, self.missing)
def with_settings(**overrides):
"""Allows you to define settings that are required for this
function to work"""
def wrapped(func):
@wraps(func)
def _with_settings(*args, **kwargs):
state = _override_settings(overrides)
try:
return func(*args, **kwargs)
finally:
_restore_settings(*state)
return _with_settings
return wrapped
def testcase_settings(**overrides):
def class_wrapper(cls):
state = [None] # don't polute the class with state
old_setup = cls.setUp
@wraps(cls.setUp)
def new_setup(self):
state[0] = _override_settings(overrides)
return old_setup(self)
cls.setUp = new_setup
old_teardown = cls.tearDown
@wraps(cls.tearDown)
def new_teardown(self):
try:
return old_teardown(self)
finally:
_restore_settings(*state[0])
cls.tearDown = new_teardown
return cls
return class_wrapper
import unittest
class AlterSettingsTests(unittest.TestCase):
def setUp(self):
global settings
self.old_settings = settings
settings = _s()
def tearDown(self):
global settings
settings = self.old_settings
def test_decorator(self):
global settings
@with_settings(a=666, c=13)
def f():
self.assertEqual(settings.a, 666)
self.assertEqual(settings.b, None)
self.assertEqual(settings.c, 13)
f()
self.assertEqual(settings.a, 10)
self.assertEqual(settings.b, None)
self.assertFalse(hasattr(settings, "c"))
def test_context_manager(self):
global settings
self.assertEqual(settings.a, 10)
self.assertEqual(settings.b, None)
self.assertFalse(hasattr(settings, "c"))
with settings_altered(a="a", q="q"):
self.assertEqual(settings.a, "a")
self.assertEqual(settings.b, None)
self.assertEqual(settings.q, "q")
self.assertEqual(settings.a, 10)
self.assertEqual(settings.b, None)
self.assertFalse(hasattr(settings, "c"))
@testcase_settings(a=0xff, c=17)
class MetaTestCase(unittest.TestCase):
def setUp(self):
self.assertEqual(settings.a, 0xff)
self.assertEqual(settings.b, 15)
self.assertEqual(settings.c, 17)
def test_one(self):
self.assertEqual(settings.a, 0xff)
self.assertEqual(settings.b, 15)
self.assertEqual(settings.c, 17)
def test_two(self):
self.assertEqual(settings.a, 0xff)
self.assertEqual(settings.b, 15)
self.assertEqual(settings.c, 17)
def tearDown(self):
self.assertEqual(settings.a, 0xff)
self.assertEqual(settings.b, 15)
self.assertEqual(settings.c, 17)
if __name__ == "__main__":
settings = _s(42, 15)
unittest.main()
assert settings.a == 42
assert settings.b == 15
assert not hasattr(settings, "c")
assert not hasattr(settings, "q")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment