We can change settings for testing.

This commit is contained in:
Rafael Caricio 2011-08-22 18:51:39 -03:00
parent 5509c527fb
commit 83356115ae
4 changed files with 48 additions and 43 deletions

View file

@ -17,6 +17,7 @@ from django.http import HttpRequest
from django_pyvows import http_helpers from django_pyvows import http_helpers
from django_pyvows.assertions import Url, Model, Template from django_pyvows.assertions import Url, Model, Template
from django_pyvows.server import DjangoServer from django_pyvows.server import DjangoServer
from django_pyvows.settings_manager import settings_tracker
DEFAULT_PORT = 3331 DEFAULT_PORT = 3331
DEFAULT_HOST = '127.0.0.1' DEFAULT_HOST = '127.0.0.1'
@ -28,6 +29,7 @@ class DjangoContext(Vows.Context):
if not settings_path: if not settings_path:
raise RuntimeError('The settings_path argument is required.') raise RuntimeError('The settings_path argument is required.')
os.environ['DJANGO_SETTINGS_MODULE'] = settings_path os.environ['DJANGO_SETTINGS_MODULE'] = settings_path
settings_tracker.install()
def __init__(self, parent): def __init__(self, parent):
super(DjangoContext, self).__init__(parent) super(DjangoContext, self).__init__(parent)
@ -78,7 +80,7 @@ class DjangoHTTPContext(DjangoContext):
self.address = (host, port) self.address = (host, port)
self.server = DjangoServer(host, port) self.server = DjangoServer(host, port)
self.server.start() self.server.start(self.settings)
def __init__(self, parent): def __init__(self, parent):
super(DjangoHTTPContext, self).__init__(parent) super(DjangoHTTPContext, self).__init__(parent)

View file

@ -11,7 +11,7 @@
import sys import sys
import urllib2 import urllib2
from threading import Thread from threading import Thread, local, current_thread
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from pyvows import Vows from pyvows import Vows
@ -137,9 +137,14 @@ class DjangoServer(HTTPServer, object):
HTTPServer.__init__(self, (host, int(port)), WSGIRequestHandler) HTTPServer.__init__(self, (host, int(port)), WSGIRequestHandler)
self.app = WSGIHandler() self.app = WSGIHandler()
def start(self): def start(self, settings):
self.server_activate() self.server_activate()
def make_response(): def make_response():
thread = current_thread()
if not hasattr(thread, "settings"):
thread.settings = local()
for key, value in settings.items():
setattr(thread.settings, key, value)
while True: while True:
self.handle_request() self.handle_request()
self.thr = Thread(target=make_response) self.thr = Thread(target=make_response)

View file

@ -9,25 +9,34 @@
# Copyright (c) 2011 Rafael Caricio rafael@caricio.com # Copyright (c) 2011 Rafael Caricio rafael@caricio.com
import sys import sys
from threading import current_thread
class ModulesTracker(object): class SettingsTracker(object):
def install(self): def install(self):
self.previous_modules = sys.modules.copy() actual_import = __builtins__['__import__']
self.real_import = __builtins__['__import__'] if actual_import != self._import:
__builtins__['__import__'] = self._import self.real_import = actual_import
self.new_modules = {} __builtins__['__import__'] = self._import
def _import(self, name, globals=None, locals=None, fromlist=[], level=-1): def _import(self, name, globals=None, locals=None, fromlist=[], level=-1):
result = apply(self.real_import, (name, globals, locals, fromlist, level)) result = apply(self.real_import, (name, globals, locals, fromlist, level))
self.new_modules[name] = 1 if name == 'django.conf':
result.settings = VowsSettings(result.settings)
elif name == "django" and 'conf' in (fromlist or []):
result.conf.settings = VowsSettings(result.settings)
return result return result
def reload(self): class VowsSettings(object):
for modname in self.new_modules.keys():
if not self.previous_modules.has_key(modname):
del(sys.modules[modname])
def uninstall(self): def __init__(self, original_settings):
__builtins__['__import__'] = self.real_import self.original_settings = original_settings
def __getattr__(self, attr_name):
thread = current_thread()
if hasattr(thread, "settings"):
if hasattr(thread.settings, attr_name):
return getattr(thread.settings, attr_name)
return getattr(self.original_settings, attr_name)
settings_tracker = SettingsTracker()

View file

@ -11,44 +11,33 @@
from pyvows import Vows, expect from pyvows import Vows, expect
from django_pyvows.context import DjangoContext, DjangoHTTPContext from django_pyvows.context import DjangoContext, DjangoHTTPContext
from django_pyvows.settings_manager import ModulesTracker #from django_pyvows.settings_manager import settings_tracker
@Vows.batch @Vows.batch
class SettingsVows(DjangoContext): class SettingsVows(DjangoContext):
class WhenIUseTheModulesTracker(DjangoContext): #class WhenIUseTheModulesTracker(DjangoContext):
def topic(self): #def topic(self):
modules_tracker = ModulesTracker() #settings_tracker.install()
modules_tracker.install() #import to_test
import to_test #return modules_tracker
return modules_tracker
def should_track_the_new_imported_module(self, topic): #def should_track_the_new_imported_module(self, topic):
expect('to_test' in topic.new_modules).to_be_true() #expect('to_test' in topic.new_modules).to_be_true()
class WhenIReloadTheImportedModule(DjangoContext): #class WhenIReloadTheImportedModule(DjangoContext):
def topic(self, modules_tracker): #def topic(self, modules_tracker):
import to_test #import to_test
imported_first_time_at = to_test.imported_at #imported_first_time_at = to_test.imported_at
modules_tracker.reload() #modules_tracker.reload()
import to_test #import to_test
return (modules_tracker, imported_first_time_at, to_test.imported_at) #return (modules_tracker, imported_first_time_at, to_test.imported_at)
def should_be_different_instances(self, topic): #def should_be_different_instances(self, topic):
expect(topic[1]).not_to_equal(topic[2]) #expect(topic[1]).not_to_equal(topic[2])
class WhenIUninstall(DjangoContext):
def topic(self, last_topic):
modules_tracker = last_topic[0]
modules_tracker.uninstall()
return __builtins__['__import__']
def should_be_restored_to_original_import_function(self, topic):
expect(topic.__module__).to_equal('__builtin__')
class CannotSayHelloWithoutName(DjangoHTTPContext): class CannotSayHelloWithoutName(DjangoHTTPContext):