More tests and refactory in some parts of the project.
This commit is contained in:
parent
4759d5299b
commit
c8390ed7da
10 changed files with 153 additions and 36 deletions
|
@ -27,6 +27,9 @@ class Model(object):
|
||||||
self.context = context
|
self.context = context
|
||||||
self.model = model
|
self.model = model
|
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs):
|
||||||
|
return self.model(*args, **kwargs)
|
||||||
|
|
||||||
class Template(object):
|
class Template(object):
|
||||||
def __init__(self, template_name, context):
|
def __init__(self, template_name, context):
|
||||||
self.template_name = template_name
|
self.template_name = template_name
|
||||||
|
|
|
@ -34,7 +34,7 @@ class DjangoContext(Vows.Context):
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
super(DjangoContext, self).__init__(parent)
|
super(DjangoContext, self).__init__(parent)
|
||||||
self.settings = {}
|
self.settings = {}
|
||||||
self.ignore('get_settings', 'template', 'request', 'model', 'url',
|
self.ignore('get_settings', 'template', 'request', 'model', 'url', 'find_in_parent',
|
||||||
'start_environment', 'port', 'host', 'get_url', 'get', 'post')
|
'start_environment', 'port', 'host', 'get_url', 'get', 'post')
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
|
@ -64,13 +64,19 @@ class DjangoContext(Vows.Context):
|
||||||
def post(self, path, params):
|
def post(self, path, params):
|
||||||
return http_helpers.post(self.get_url(path), params)
|
return http_helpers.post(self.get_url(path), params)
|
||||||
|
|
||||||
def get_url(self, path):
|
def find_in_parent(self, attr_name):
|
||||||
ctx = self.parent
|
ctx = self.parent
|
||||||
while ctx:
|
while ctx:
|
||||||
if hasattr(ctx, 'get_url'):
|
if hasattr(ctx, attr_name):
|
||||||
return ctx.get_url(path)
|
return getattr(ctx, attr_name)
|
||||||
ctx = ctx.parent
|
ctx = ctx.parent
|
||||||
return ""
|
raise ValueError('Host could not be found in the context or any of its parents')
|
||||||
|
|
||||||
|
def get_url(self, path):
|
||||||
|
try:
|
||||||
|
return self.find_in_parent('get_url')(path)
|
||||||
|
except ValueError:
|
||||||
|
return path
|
||||||
|
|
||||||
class DjangoHTTPContext(DjangoContext):
|
class DjangoHTTPContext(DjangoContext):
|
||||||
|
|
||||||
|
@ -90,21 +96,13 @@ class DjangoHTTPContext(DjangoContext):
|
||||||
def host(self):
|
def host(self):
|
||||||
if hasattr(self, 'address'):
|
if hasattr(self, 'address'):
|
||||||
return self.address[0]
|
return self.address[0]
|
||||||
|
return self.find_in_parent('host')
|
||||||
if self.parent and hasattr(self.parent, 'host'):
|
|
||||||
return self.parent.host
|
|
||||||
|
|
||||||
raise RuntimeError('Host could not be found in the context or any of its parents')
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def port(self):
|
def port(self):
|
||||||
if hasattr(self, 'address'):
|
if hasattr(self, 'address'):
|
||||||
return self.address[1]
|
return self.address[1]
|
||||||
|
return self.find_in_parent('port')
|
||||||
if self.parent and hasattr(self.parent, 'port'):
|
|
||||||
return self.parent.port
|
|
||||||
|
|
||||||
raise RuntimeError('Port could not be found in the context or any of its parents')
|
|
||||||
|
|
||||||
def get_url(self, path):
|
def get_url(self, path):
|
||||||
if re.match('^https?:\/\/', path):
|
if re.match('^https?:\/\/', path):
|
||||||
|
|
|
@ -94,14 +94,6 @@ class WSGIRequestHandler(BaseHTTPRequestHandler):
|
||||||
self.wfile.flush()
|
self.wfile.flush()
|
||||||
|
|
||||||
def start_response(status, response_headers, exc_info=None):
|
def start_response(status, response_headers, exc_info=None):
|
||||||
if exc_info:
|
|
||||||
try:
|
|
||||||
if headers_sent:
|
|
||||||
raise exc_info[0], exc_info[1], exc_info[2]
|
|
||||||
finally:
|
|
||||||
exc_info = None
|
|
||||||
elif headers_set:
|
|
||||||
raise AssertionError('Headers already set')
|
|
||||||
headers_set[:] = [status, response_headers]
|
headers_set[:] = [status, response_headers]
|
||||||
return write
|
return write
|
||||||
|
|
||||||
|
@ -109,8 +101,6 @@ class WSGIRequestHandler(BaseHTTPRequestHandler):
|
||||||
try:
|
try:
|
||||||
for data in application_iter:
|
for data in application_iter:
|
||||||
write(data)
|
write(data)
|
||||||
# make sure the headers are sent
|
|
||||||
if not headers_sent:
|
|
||||||
write('')
|
write('')
|
||||||
finally:
|
finally:
|
||||||
if hasattr(application_iter, 'close'):
|
if hasattr(application_iter, 'close'):
|
||||||
|
@ -125,11 +115,6 @@ class WSGIRequestHandler(BaseHTTPRequestHandler):
|
||||||
def log_request(self, *args, **kwargs):
|
def log_request(self, *args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def log_error(self, *args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def log_message(self, *args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class DjangoServer(HTTPServer, object):
|
class DjangoServer(HTTPServer, object):
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
from pyvows import Vows, expect
|
from pyvows import Vows, expect
|
||||||
|
|
||||||
from django_pyvows.context import DjangoContext
|
from django_pyvows.context import DjangoContext, DjangoHTTPContext
|
||||||
|
|
||||||
@Vows.batch
|
@Vows.batch
|
||||||
class ContextTest(Vows.Context):
|
class ContextTest(Vows.Context):
|
||||||
|
@ -26,3 +26,77 @@ class ContextTest(Vows.Context):
|
||||||
|
|
||||||
def should_have_nice_error_message(self, topic):
|
def should_have_nice_error_message(self, topic):
|
||||||
expect(topic).to_have_an_error_message_of('The settings_path argument is required.')
|
expect(topic).to_have_an_error_message_of('The settings_path argument is required.')
|
||||||
|
|
||||||
|
class WithinANoDjangoContext(Vows.Context):
|
||||||
|
|
||||||
|
class TheGetUrlMethod(DjangoContext):
|
||||||
|
|
||||||
|
def topic(self):
|
||||||
|
return self.get_url('/')
|
||||||
|
|
||||||
|
def should_return_the_same_path(self, topic):
|
||||||
|
expect(topic).to_equal('/')
|
||||||
|
|
||||||
|
class TheHost(DjangoHTTPContext):
|
||||||
|
|
||||||
|
def topic(self):
|
||||||
|
return self.host
|
||||||
|
|
||||||
|
def should_return_an_error(self, topic):
|
||||||
|
expect(topic).to_be_an_error_like(ValueError)
|
||||||
|
|
||||||
|
class ThePort(DjangoHTTPContext):
|
||||||
|
|
||||||
|
def topic(self):
|
||||||
|
return self.port
|
||||||
|
|
||||||
|
def should_return_an_error(self, topic):
|
||||||
|
expect(topic).to_be_an_error_like(ValueError)
|
||||||
|
|
||||||
|
class WithinAServer(DjangoHTTPContext):
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
self.start_server(port=8085)
|
||||||
|
|
||||||
|
class WithinDjangoHTTPContextTheGetUrlMethod(DjangoHTTPContext):
|
||||||
|
|
||||||
|
def topic(self):
|
||||||
|
return self.get_url('http://127.0.0.1:8085/complete_url/')
|
||||||
|
|
||||||
|
def when_passed_a_complete_url_should_return_the_url_without_modification(self, topic):
|
||||||
|
expect(topic).to_equal('http://127.0.0.1:8085/complete_url/')
|
||||||
|
|
||||||
|
class InADjangoHTTPContext(DjangoHTTPContext):
|
||||||
|
|
||||||
|
def topic(self):
|
||||||
|
return self.get_url('/')
|
||||||
|
|
||||||
|
def the_get_url_should_return_a_well_formed_url(self, topic):
|
||||||
|
expect(topic).to_equal('http://127.0.0.1:8085/')
|
||||||
|
|
||||||
|
class ANoDjangoContext(Vows.Context):
|
||||||
|
|
||||||
|
class TheHost(DjangoHTTPContext):
|
||||||
|
|
||||||
|
def topic(self):
|
||||||
|
return self.host
|
||||||
|
|
||||||
|
def should_be_equal_to_the_host_in_out_context(self, topic):
|
||||||
|
expect(topic).to_equal('127.0.0.1')
|
||||||
|
|
||||||
|
class ThePort(DjangoHTTPContext):
|
||||||
|
|
||||||
|
def topic(self):
|
||||||
|
return self.port
|
||||||
|
|
||||||
|
def should_be_equal_to_the_port_in_out_context(self, topic):
|
||||||
|
expect(topic).to_equal(8085)
|
||||||
|
|
||||||
|
class AnDjangoContext(DjangoContext):
|
||||||
|
|
||||||
|
def topic(self):
|
||||||
|
return self.get_url('/')
|
||||||
|
|
||||||
|
def the_get_url_method_should_return_a_well_formed_url(self, topic):
|
||||||
|
expect(topic).to_equal('http://127.0.0.1:8085/')
|
||||||
|
|
||||||
|
|
1
vows/fixtures/the_file.txt
Normal file
1
vows/fixtures/the_file.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
the contents
|
|
@ -13,6 +13,7 @@ from django_pyvows.context import DjangoContext
|
||||||
|
|
||||||
DjangoContext.start_environment("sandbox.settings")
|
DjangoContext.start_environment("sandbox.settings")
|
||||||
|
|
||||||
|
from django.db import models
|
||||||
from sandbox.main.models import StringModel
|
from sandbox.main.models import StringModel
|
||||||
|
|
||||||
@Vows.batch
|
@Vows.batch
|
||||||
|
@ -31,4 +32,15 @@ class ModelVows(DjangoContext):
|
||||||
'name': 'something'
|
'name': 'something'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def should_have_a_method_to_call(self, topic):
|
||||||
|
expect(hasattr(topic, '__call__')).to_be_true()
|
||||||
|
|
||||||
|
class WhenICreateANewInstance(DjangoContext):
|
||||||
|
|
||||||
|
def topic(self, model):
|
||||||
|
return model()
|
||||||
|
|
||||||
|
def should_be_an_instance_of_django_model_class(self, topic):
|
||||||
|
expect(isinstance(topic, models.Model)).to_be_true()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,5 @@ def say_hello(request):
|
||||||
def post_it(request):
|
def post_it(request):
|
||||||
return HttpResponse(request.POST['value'])
|
return HttpResponse(request.POST['value'])
|
||||||
|
|
||||||
def get_setting(request, attr):
|
def post_file(request):
|
||||||
return HttpResponse(str(getattr(settings, attr)))
|
return HttpResponse(request.FILES['the_file'].read().strip())
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ urlpatterns = patterns('',
|
||||||
url(r'^$', 'sandbox.main.views.home', name='home'),
|
url(r'^$', 'sandbox.main.views.home', name='home'),
|
||||||
url(r'^say/$', 'sandbox.main.views.say_hello', name='say_hello'),
|
url(r'^say/$', 'sandbox.main.views.say_hello', name='say_hello'),
|
||||||
url(r'^post_it/$', 'sandbox.main.views.post_it', name='post_it'),
|
url(r'^post_it/$', 'sandbox.main.views.post_it', name='post_it'),
|
||||||
url(r'^settings/(?P<attr>[\w_]+)/?$', 'sandbox.main.views.get_setting', name='get_setting'),
|
url(r'^post_file/$', 'sandbox.main.views.post_file', name='post_file'),
|
||||||
|
|
||||||
# url(r'^sandbox/', include('sandbox.foo.urls')),
|
# url(r'^sandbox/', include('sandbox.foo.urls')),
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,14 @@
|
||||||
# http://www.opensource.org/licenses/mit-license
|
# http://www.opensource.org/licenses/mit-license
|
||||||
# Copyright (c) 2011 Rafael Caricio rafael@caricio.com
|
# Copyright (c) 2011 Rafael Caricio rafael@caricio.com
|
||||||
|
|
||||||
|
import urllib2
|
||||||
|
from os.path import abspath, join, dirname
|
||||||
|
|
||||||
from django_pyvows.context import DjangoContext, DjangoHTTPContext
|
from django_pyvows.context import DjangoContext, DjangoHTTPContext
|
||||||
from django_pyvows.assertions import *
|
from django_pyvows.assertions import *
|
||||||
|
|
||||||
|
TEST_FILE_PATH = abspath(join(dirname(__file__), 'fixtures/the_file.txt'))
|
||||||
|
|
||||||
@Vows.batch
|
@Vows.batch
|
||||||
class HttpContextVows(DjangoHTTPContext):
|
class HttpContextVows(DjangoHTTPContext):
|
||||||
|
|
||||||
|
@ -56,3 +61,19 @@ class HttpContextVows(DjangoHTTPContext):
|
||||||
def should_be_posted(self, topic):
|
def should_be_posted(self, topic):
|
||||||
expect(topic.read()).to_equal('posted!')
|
expect(topic.read()).to_equal('posted!')
|
||||||
|
|
||||||
|
class PostFile(DjangoContext):
|
||||||
|
|
||||||
|
def topic(self):
|
||||||
|
return self.post('/post_file/', {'the_file': open(TEST_FILE_PATH) })
|
||||||
|
|
||||||
|
def should_be_posted_to_the_server(self, topic):
|
||||||
|
expect(topic.read()).to_equal("the contents")
|
||||||
|
|
||||||
|
class PostToNotFound(DjangoContext):
|
||||||
|
|
||||||
|
def topic(self):
|
||||||
|
return self.post('/post_/', {'the_file': open(TEST_FILE_PATH) })
|
||||||
|
|
||||||
|
def should_be_thrown_an_error(self, topic):
|
||||||
|
expect(topic).to_be_an_error_like(urllib2.HTTPError)
|
||||||
|
|
||||||
|
|
24
vows/version_vows.py
Normal file
24
vows/version_vows.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# django-pyvows extensions
|
||||||
|
# https://github.com/rafaelcaricio/django-pyvows
|
||||||
|
|
||||||
|
# Licensed under the MIT license:
|
||||||
|
# http://www.opensource.org/licenses/mit-license
|
||||||
|
# Copyright (c) 2011 Rafael Caricio rafael@caricio.com
|
||||||
|
|
||||||
|
from types import TupleType
|
||||||
|
|
||||||
|
from pyvows import Vows, expect
|
||||||
|
|
||||||
|
|
||||||
|
@Vows.batch
|
||||||
|
class VersionVows(Vows.Context):
|
||||||
|
|
||||||
|
def topic(self):
|
||||||
|
from django_pyvows.version import __version__
|
||||||
|
return __version__
|
||||||
|
|
||||||
|
def should_be_an_tuple(self, topic):
|
||||||
|
expect(topic).to_be_instance_of(TupleType)
|
Reference in a new issue