From c8390ed7da70c31f29b4af20d37325de198d79a2 Mon Sep 17 00:00:00 2001 From: Rafael Caricio Date: Thu, 25 Aug 2011 18:19:24 -0300 Subject: [PATCH] More tests and refactory in some parts of the project. --- django_pyvows/assertions.py | 3 ++ django_pyvows/context.py | 28 +++++++------- django_pyvows/server.py | 17 +-------- vows/context_vows.py | 76 ++++++++++++++++++++++++++++++++++++- vows/fixtures/the_file.txt | 1 + vows/model_vows.py | 12 ++++++ vows/sandbox/main/views.py | 5 +-- vows/sandbox/urls.py | 2 +- vows/server_vows.py | 21 ++++++++++ vows/version_vows.py | 24 ++++++++++++ 10 files changed, 153 insertions(+), 36 deletions(-) create mode 100644 vows/fixtures/the_file.txt create mode 100644 vows/version_vows.py diff --git a/django_pyvows/assertions.py b/django_pyvows/assertions.py index 5a925a0..b1cf932 100644 --- a/django_pyvows/assertions.py +++ b/django_pyvows/assertions.py @@ -27,6 +27,9 @@ class Model(object): self.context = context self.model = model + def __call__(self, *args, **kwargs): + return self.model(*args, **kwargs) + class Template(object): def __init__(self, template_name, context): self.template_name = template_name diff --git a/django_pyvows/context.py b/django_pyvows/context.py index 3519ca2..a97cdd1 100644 --- a/django_pyvows/context.py +++ b/django_pyvows/context.py @@ -34,7 +34,7 @@ class DjangoContext(Vows.Context): def __init__(self, parent): super(DjangoContext, self).__init__(parent) 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') def setup(self): @@ -64,13 +64,19 @@ class DjangoContext(Vows.Context): def post(self, 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 while ctx: - if hasattr(ctx, 'get_url'): - return ctx.get_url(path) + if hasattr(ctx, attr_name): + return getattr(ctx, attr_name) 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): @@ -90,21 +96,13 @@ class DjangoHTTPContext(DjangoContext): def host(self): if hasattr(self, 'address'): return self.address[0] - - 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') + return self.find_in_parent('host') @property def port(self): if hasattr(self, 'address'): return self.address[1] - - 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') + return self.find_in_parent('port') def get_url(self, path): if re.match('^https?:\/\/', path): diff --git a/django_pyvows/server.py b/django_pyvows/server.py index 5d793d9..1324c73 100644 --- a/django_pyvows/server.py +++ b/django_pyvows/server.py @@ -94,14 +94,6 @@ class WSGIRequestHandler(BaseHTTPRequestHandler): self.wfile.flush() 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] return write @@ -109,9 +101,7 @@ class WSGIRequestHandler(BaseHTTPRequestHandler): try: for data in application_iter: write(data) - # make sure the headers are sent - if not headers_sent: - write('') + write('') finally: if hasattr(application_iter, 'close'): application_iter.close() @@ -125,11 +115,6 @@ class WSGIRequestHandler(BaseHTTPRequestHandler): def log_request(self, *args, **kwargs): pass - def log_error(self, *args): - pass - - def log_message(self, *args): - pass class DjangoServer(HTTPServer, object): diff --git a/vows/context_vows.py b/vows/context_vows.py index 023a5bd..e4ba9e5 100644 --- a/vows/context_vows.py +++ b/vows/context_vows.py @@ -10,7 +10,7 @@ from pyvows import Vows, expect -from django_pyvows.context import DjangoContext +from django_pyvows.context import DjangoContext, DjangoHTTPContext @Vows.batch class ContextTest(Vows.Context): @@ -26,3 +26,77 @@ class ContextTest(Vows.Context): def should_have_nice_error_message(self, topic): 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/') + diff --git a/vows/fixtures/the_file.txt b/vows/fixtures/the_file.txt new file mode 100644 index 0000000..56627f7 --- /dev/null +++ b/vows/fixtures/the_file.txt @@ -0,0 +1 @@ +the contents diff --git a/vows/model_vows.py b/vows/model_vows.py index 73d78e7..5760e13 100644 --- a/vows/model_vows.py +++ b/vows/model_vows.py @@ -13,6 +13,7 @@ from django_pyvows.context import DjangoContext DjangoContext.start_environment("sandbox.settings") +from django.db import models from sandbox.main.models import StringModel @Vows.batch @@ -31,4 +32,15 @@ class ModelVows(DjangoContext): '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() + diff --git a/vows/sandbox/main/views.py b/vows/sandbox/main/views.py index 7849090..9490e96 100644 --- a/vows/sandbox/main/views.py +++ b/vows/sandbox/main/views.py @@ -28,6 +28,5 @@ def say_hello(request): def post_it(request): return HttpResponse(request.POST['value']) -def get_setting(request, attr): - return HttpResponse(str(getattr(settings, attr))) - +def post_file(request): + return HttpResponse(request.FILES['the_file'].read().strip()) diff --git a/vows/sandbox/urls.py b/vows/sandbox/urls.py index 3d75bf5..cf68581 100644 --- a/vows/sandbox/urls.py +++ b/vows/sandbox/urls.py @@ -18,7 +18,7 @@ urlpatterns = patterns('', url(r'^$', 'sandbox.main.views.home', name='home'), 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'^settings/(?P[\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')), diff --git a/vows/server_vows.py b/vows/server_vows.py index 678fc25..7124462 100644 --- a/vows/server_vows.py +++ b/vows/server_vows.py @@ -8,9 +8,14 @@ # http://www.opensource.org/licenses/mit-license # 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.assertions import * +TEST_FILE_PATH = abspath(join(dirname(__file__), 'fixtures/the_file.txt')) + @Vows.batch class HttpContextVows(DjangoHTTPContext): @@ -56,3 +61,19 @@ class HttpContextVows(DjangoHTTPContext): def should_be_posted(self, topic): 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) + diff --git a/vows/version_vows.py b/vows/version_vows.py new file mode 100644 index 0000000..922cdbc --- /dev/null +++ b/vows/version_vows.py @@ -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)