11 | {% block body %}
12 |
13 | {% block content_title %}{% endblock %}
14 |
15 |
16 | {% block content %}{% endblock %}
17 |
18 | {% endblock %}
19 |
20 |
21 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templates/blog/.svn/text-base/post_archive_year.html.svn-base:
--------------------------------------------------------------------------------
1 | {% extends "blog/base_blog.html" %}
2 |
3 |
4 | {% block title %}Post archive for {{ year }}{% endblock %}
5 | {% block body_class %}{{ block.super }} post_archive_year{% endblock %}
6 |
7 |
8 | {% block content_title %}
9 |
11 | {% block body %}
12 |
13 | {% block content_title %}{% endblock %}
14 |
15 |
16 | {% block content %}{% endblock %}
17 |
18 | {% endblock %}
19 |
20 |
21 |
--------------------------------------------------------------------------------
/fixture/examples/pylons_example/addressbook/test.ini:
--------------------------------------------------------------------------------
1 | #
2 | # addressbook - Pylons testing environment configuration
3 | #
4 | # The %(here)s variable will be replaced with the parent directory of this file
5 | #
6 | [DEFAULT]
7 | debug = true
8 | # Uncomment and replace with the address which should receive any error reports
9 | #email_to = you@yourdomain.com
10 | smtp_server = localhost
11 | error_email_from = paste@localhost
12 |
13 | [server:main]
14 | use = egg:Paste#http
15 | host = 127.0.0.1
16 | port = 5000
17 |
18 | [app:main]
19 | use = config:development.ini
20 |
21 | # Add additional test specific configuration options as necessary.
22 | sqlalchemy.url = sqlite:///%(here)s/tests.db
--------------------------------------------------------------------------------
/fixture/test/test_loadable/test_django/util.py:
--------------------------------------------------------------------------------
1 | """This is mostly a copy of methods and internal classes from loadable"""
2 |
3 | from django.db.models.loading import get_models
4 | from fixture.loadable.loadable import DeferredStoredObject
5 |
6 | def assert_empty(mod):
7 | for model in get_models(mod):
8 | assert model.objects.count() == 0
9 |
10 | def resolve_stored_object(column_val):
11 | if type(column_val)==DeferredStoredObject:
12 | return column_val.get_stored_object_from_loader(self)
13 | else:
14 | return column_val
15 |
16 | def get_column_vals(row):
17 | for c in row.columns():
18 | yield (c, resolve_stored_object(getattr(row, c)))
--------------------------------------------------------------------------------
/docs/source/api/fixture.django_testcase.rst:
--------------------------------------------------------------------------------
1 | ------------------------------------------
2 | fixture.django_testcase
3 | ------------------------------------------
4 |
5 | .. automodule:: fixture.django_testcase
6 |
7 | .. autoclass:: fixture.django_testcase.FixtureTestCase
8 | :show-inheritance:
9 | :members: _fixture_setup, _fixture_teardown
10 |
11 | .. attribute:: datasets
12 |
13 | This is a list of :class:`DataSets ` that will be created and destroyed for each test method.
14 | The result of setting them up will be referenced by the :attr:`data`
15 |
16 | .. attribute:: data
17 |
18 | Any :attr:`datasets` found are loaded and refereneced here for later teardown
19 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import sys
3 | import os
4 | sys.path.append(os.path.dirname(__file__))
5 | from django.core.management import execute_manager
6 | try:
7 | import settings # Assumed to be in the same directory.
8 | except ImportError:
9 | import sys
10 | sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
11 | sys.exit(1)
12 |
13 | def main():
14 | execute_manager(settings)
15 |
16 | if __name__ == "__main__":
17 | main()
18 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templates/blog/post_archive_day.html:
--------------------------------------------------------------------------------
1 | {% extends "blog/base_blog.html" %}
2 |
3 |
4 | {% block title %}Post archive for {{ day|date:"d F Y" }}{% endblock %}
5 | {% block body_class %}{{ block.super }} post_archive_day{% endblock %}
6 |
7 |
8 | {% block content_title %}
9 | Post archive for {{ day|date:"d F Y" }}
10 | {% endblock %}
11 |
12 |
13 | {% block content %}
14 |
15 | {% for post in object_list %}
16 |
17 |
18 |
{{ post.publish|date:"Y F d" }}
19 |
{{ post.tease }}
20 |
21 | {% endfor %}
22 |
23 | {% endblock %}
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templates/blog/post_archive_month.html:
--------------------------------------------------------------------------------
1 | {% extends "blog/base_blog.html" %}
2 |
3 |
4 | {% block title %}Post archive for {{ month|date:"F Y" }}{% endblock %}
5 | {% block body_class %}{{ block.super }} post_archive_month{% endblock %}
6 |
7 |
8 | {% block content_title %}
9 | Post archive for {{ month|date:"F Y" }}
10 | {% endblock %}
11 |
12 |
13 | {% block content %}
14 |
15 | {% for post in object_list %}
16 |
17 |
18 |
{{ post.publish|date:"Y F d" }}
19 |
{{ post.tease }}
20 |
21 | {% endfor %}
22 |
23 | {% endblock %}
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templates/blog/.svn/text-base/post_archive_day.html.svn-base:
--------------------------------------------------------------------------------
1 | {% extends "blog/base_blog.html" %}
2 |
3 |
4 | {% block title %}Post archive for {{ day|date:"d F Y" }}{% endblock %}
5 | {% block body_class %}{{ block.super }} post_archive_day{% endblock %}
6 |
7 |
8 | {% block content_title %}
9 | Post archive for {{ day|date:"d F Y" }}
10 | {% endblock %}
11 |
12 |
13 | {% block content %}
14 |
15 | {% for post in object_list %}
16 |
17 |
18 |
{{ post.publish|date:"Y F d" }}
19 |
{{ post.tease }}
20 |
21 | {% endfor %}
22 |
23 | {% endblock %}
--------------------------------------------------------------------------------
/fixture/examples/pylons_example/addressbook/setup.cfg:
--------------------------------------------------------------------------------
1 | [egg_info]
2 | tag_build = dev
3 | tag_svn_revision = true
4 |
5 | [easy_install]
6 | find_links = http://www.pylonshq.com/download/
7 |
8 | [nosetests]
9 | with-pylons = test.ini
10 |
11 | # Babel configuration
12 | [compile_catalog]
13 | domain = addressbook
14 | directory = addressbook/i18n
15 | statistics = true
16 |
17 | [extract_messages]
18 | add_comments = TRANSLATORS:
19 | output_file = addressbook/i18n/addressbook.pot
20 | width = 80
21 |
22 | [init_catalog]
23 | domain = addressbook
24 | input_file = addressbook/i18n/addressbook.pot
25 | output_dir = addressbook/i18n
26 |
27 | [update_catalog]
28 | domain = addressbook
29 | input_file = addressbook/i18n/addressbook.pot
30 | output_dir = addressbook/i18n
31 | previous = true
32 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templates/blog/.svn/text-base/post_archive_month.html.svn-base:
--------------------------------------------------------------------------------
1 | {% extends "blog/base_blog.html" %}
2 |
3 |
4 | {% block title %}Post archive for {{ month|date:"F Y" }}{% endblock %}
5 | {% block body_class %}{{ block.super }} post_archive_month{% endblock %}
6 |
7 |
8 | {% block content_title %}
9 | Post archive for {{ month|date:"F Y" }}
10 | {% endblock %}
11 |
12 |
13 | {% block content %}
14 |
15 | {% for post in object_list %}
16 |
17 |
18 |
{{ post.publish|date:"Y F d" }}
19 |
{{ post.tease }}
20 |
21 | {% endfor %}
22 |
23 | {% endblock %}
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templates/inlines/.svn/entries:
--------------------------------------------------------------------------------
1 | 9
2 |
3 | dir
4 | 102
5 | http://django-basic-apps.googlecode.com/svn/trunk/blog/templates/inlines
6 | http://django-basic-apps.googlecode.com/svn
7 |
8 |
9 |
10 | 2008-04-23T01:32:32.573954Z
11 | 26
12 | nathan@playgroundblues.com
13 |
14 |
15 | svn:special svn:externals svn:needs-lock
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 5ae32e2a-df40-0410-a01d-45158a99d8df
28 |
29 | default.html
30 | file
31 |
32 |
33 |
34 |
35 | 2009-03-04T15:11:18.000000Z
36 | 0e1a352b8aa2b36a9abaa6c711c15923
37 | 2008-04-23T01:32:32.573954Z
38 | 26
39 | nathan@playgroundblues.com
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | 119
62 |
63 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | fixture
2 | Copyright (C) 2006 Kumar McMillan
3 |
4 | This library is free software; you can redistribute it and/or
5 | modify it under the terms of the GNU Lesser General Public
6 | License as published by the Free Software Foundation; either
7 | version 2.1 of the License, or (at your option) any later version.
8 |
9 | This library is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | Lesser General Public License for more details.
13 |
14 | You should have received a copy of the GNU Lesser General Public
15 | License along with this library; if not, write to the Free Software
16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--------------------------------------------------------------------------------
/fixture/examples/google_appengine_example/gblog/handlers.py:
--------------------------------------------------------------------------------
1 |
2 | import os
3 | import logging
4 | from google.appengine.ext import webapp
5 | from google.appengine.ext.webapp import template
6 | from gblog.models import *
7 |
8 | log = logging.getLogger()
9 |
10 | def tpl_path(template_file_name):
11 | return os.path.join(os.path.dirname(__file__), 'templates', template_file_name)
12 |
13 | class ListEntries(webapp.RequestHandler):
14 | def get(self):
15 | entries = Entry.all()
16 | entries_comments = [(e, [c for c in Comment.all().filter("entry =", e)]) for e in entries]
17 | log.info(entries_comments)
18 | tpl = {
19 | 'entries_comments': entries_comments,
20 | }
21 | self.response.out.write(template.render(tpl_path('list_entries.html'), tpl))
--------------------------------------------------------------------------------
/fixture/examples/pylons_example/addressbook/addressbook/lib/base.py:
--------------------------------------------------------------------------------
1 | """The base Controller API
2 |
3 | Provides the BaseController class for subclassing.
4 | """
5 | from pylons.controllers import WSGIController
6 | from pylons.templating import render_mako as render
7 |
8 | from addressbook.model import meta
9 |
10 | class BaseController(WSGIController):
11 |
12 | def __call__(self, environ, start_response):
13 | """Invoke the Controller"""
14 | # WSGIController.__call__ dispatches to the Controller method
15 | # the request is routed to. This routing information is
16 | # available in environ['pylons.routes_dict']
17 | try:
18 | return WSGIController.__call__(self, environ, start_response)
19 | finally:
20 | meta.Session.remove()
21 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templates/blog/category_detail.html:
--------------------------------------------------------------------------------
1 | {% extends "blog/base_blog.html" %}
2 |
3 |
4 | {% block title %}Posts for {{ category.title }}{% endblock %}
5 | {% block body_class %}{{ block.super }} category_detail{% endblock %}
6 | {% block body_id %}category_{{ category.id }}{% endblock %}
7 |
8 |
9 | {% block content_title %}
10 | Posts for {{ category.title }}
11 | {% endblock %}
12 |
13 |
14 | {% block content %}
15 | {% load markup %}
16 |
17 | {% for post in object_list %}
18 |
19 |
20 |
{{ post.publish|date:"Y F d" }}
21 |
{{ post.tease }}
22 |
23 | {% endfor %}
24 |
25 | {% endblock %}
--------------------------------------------------------------------------------
/fixture/examples/pylons_example/addressbook/README.txt:
--------------------------------------------------------------------------------
1 | This file is for you to describe the addressbook application. Typically
2 | you would include information such as the information below:
3 |
4 | Installation and Setup
5 | ======================
6 |
7 | Install ``addressbook`` using easy_install::
8 |
9 | easy_install addressbook
10 |
11 | Make a config file as follows::
12 |
13 | paster make-config addressbook config.ini
14 |
15 | Tweak the config file as appropriate and then setup the application::
16 |
17 | paster setup-app config.ini
18 |
19 | Then you are ready to go.
20 |
21 | About This Example App
22 | ======================
23 |
24 | SQLAlchemy support added by following prompts on the command line of paster create. Note that the requirement has been decremented to ==0.4.8 since fixture does not support 0.5+ yet.
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templates/blog/.svn/text-base/category_detail.html.svn-base:
--------------------------------------------------------------------------------
1 | {% extends "blog/base_blog.html" %}
2 |
3 |
4 | {% block title %}Posts for {{ category.title }}{% endblock %}
5 | {% block body_class %}{{ block.super }} category_detail{% endblock %}
6 | {% block body_id %}category_{{ category.id }}{% endblock %}
7 |
8 |
9 | {% block content_title %}
10 | Posts for {{ category.title }}
11 | {% endblock %}
12 |
13 |
14 | {% block content %}
15 | {% load markup %}
16 |
17 | {% for post in object_list %}
18 |
19 |
20 |
{{ post.publish|date:"Y F d" }}
21 |
{{ post.tease }}
22 |
23 | {% endfor %}
24 |
25 | {% endblock %}
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templates/.svn/entries:
--------------------------------------------------------------------------------
1 | 9
2 |
3 | dir
4 | 102
5 | http://django-basic-apps.googlecode.com/svn/trunk/blog/templates
6 | http://django-basic-apps.googlecode.com/svn
7 |
8 |
9 |
10 | 2008-10-14T15:29:28.448229Z
11 | 90
12 | nathan@playgroundblues.com
13 |
14 |
15 | svn:special svn:externals svn:needs-lock
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 5ae32e2a-df40-0410-a01d-45158a99d8df
28 |
29 | inlines
30 | dir
31 |
32 | blog
33 | dir
34 |
35 | feeds
36 | dir
37 |
38 | admin
39 | dir
40 |
41 | base.html
42 | file
43 |
44 |
45 |
46 |
47 | 2009-03-04T15:11:19.000000Z
48 | 6bd08ae684a2d1c88b41e3772ea9d95d
49 | 2008-10-14T15:29:28.448229Z
50 | 90
51 | nathan@playgroundblues.com
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | 528
74 |
75 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from django.utils.translation import ugettext_lazy as _
3 | from django.contrib.auth.models import User
4 |
5 | class Category(models.Model):
6 | title = models.CharField(_('title'), max_length=100)
7 | slug = models.SlugField(_('slug'), unique=True)
8 |
9 | def __unicode__(self):
10 | return u'%s' % self.title
11 |
12 | class Post(models.Model):
13 | title = models.CharField(_('title'), max_length=200)
14 | author = models.ForeignKey(User, blank=True, null=True)
15 | body = models.TextField(_('body'))
16 | created = models.DateTimeField(_('created'), auto_now_add=True)
17 | modified = models.DateTimeField(_('modified'), auto_now=True)
18 | categories = models.ManyToManyField(Category, blank=True)
19 |
20 | def __unicode__(self):
21 | return u'%s' % self.title
22 |
--------------------------------------------------------------------------------
/fixture/examples/pylons_example/addressbook/addressbook/tests/functional/test_book.py:
--------------------------------------------------------------------------------
1 |
2 | from addressbook.model import meta, Person
3 | from addressbook.datasets import PersonData, AddressData
4 | from addressbook.tests import *
5 |
6 | class TestBookController(TestController):
7 |
8 | def setUp(self):
9 | super(TestBookController, self).setUp()
10 | self.data = dbfixture.data(PersonData) # AddressData loads implicitly
11 | self.data.setup()
12 |
13 | def tearDown(self):
14 | self.data.teardown()
15 | super(TestBookController, self).tearDown()
16 |
17 | def test_index(self):
18 | response = self.app.get(url(controller='book'))
19 | print response
20 | assert PersonData.joe_gibbs.name in response
21 | assert PersonData.joe_gibbs.email in response
22 | assert AddressData.joe_in_montego.address in response
23 | assert AddressData.joe_in_ny.address in response
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/.svn/text-base/README.txt.svn-base:
--------------------------------------------------------------------------------
1 | ===========================================
2 | Django Basic Blog
3 | http://code.google.com/p/django-basic-apps/
4 | ===========================================
5 |
6 | A simple blog application for Django projects.
7 |
8 | To install this app, simply create a folder somewhere in
9 | your PYTHONPATH named 'basic' and place the 'blog'
10 | app inside. Then add 'basic.blog' to your projects
11 | INSTALLED_APPS list in your settings.py file.
12 |
13 | === Dependancies ===
14 | * Basic Inlines
15 | * [http://www.djangoproject.com/documentation/add_ons/#comments Django Comments]
16 | * [http://code.google.com/p/django-tagging Django Tagging]
17 | * [http://www.djangoproject.com/documentation/add_ons/#markup Markup]
18 | * [http://www.crummy.com/software/BeautifulSoup/ BeautifulSoup] - only if you want to use the [http://code.google.com/p/django-basic-blog/wiki/BlogInlinesProposal render_inlines] filter, otherwise it's not necessary.
--------------------------------------------------------------------------------
/fixture/examples/google_appengine_example/tests/test_list_entries.py:
--------------------------------------------------------------------------------
1 |
2 | import unittest
3 | from fixture import GoogleDatastoreFixture, DataSet
4 | from fixture.style import NamedDataStyle
5 | from gblog import application, models
6 | from webtest import TestApp
7 | from datasets import CommentData, EntryData
8 |
9 | datafixture = GoogleDatastoreFixture(env=models, style=NamedDataStyle())
10 |
11 | class TestListEntries(unittest.TestCase):
12 | def setUp(self):
13 | self.app = TestApp(application)
14 | self.data = datafixture.data(CommentData, EntryData)
15 | self.data.setup()
16 |
17 | def tearDown(self):
18 | self.data.teardown()
19 |
20 | def test_entries(self):
21 | response = self.app.get("/")
22 | print response
23 |
24 | assert EntryData.great_monday.title in response
25 | assert EntryData.great_monday.body in response
26 |
27 | assert CommentData.monday_liked_it.comment in response
28 | assert CommentData.monday_sucked.comment in response
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templates/blog/post_list.html:
--------------------------------------------------------------------------------
1 | {% extends "blog/base_blog.html" %}
2 |
3 |
4 | {% block title %}Post archive{% endblock %}
5 | {% block body_class %}{{ block.super }} post_list{% endblock %}
6 |
7 |
8 | {% block content_title %}
9 | Post archive
10 | {% endblock %}
11 |
12 |
13 | {% block content %}
14 |
15 | {% for post in object_list %}
16 |
17 |
18 |
{{ post.publish|date:"Y F d" }}
19 |
{{ post.tease }}
20 |
21 | {% endfor %}
22 |
23 |
24 | {% if is_paginated %}
25 |
34 | {% endif %}
35 | {% endblock %}
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templates/blog/.svn/text-base/post_list.html.svn-base:
--------------------------------------------------------------------------------
1 | {% extends "blog/base_blog.html" %}
2 |
3 |
4 | {% block title %}Post archive{% endblock %}
5 | {% block body_class %}{{ block.super }} post_list{% endblock %}
6 |
7 |
8 | {% block content_title %}
9 | Post archive
10 | {% endblock %}
11 |
12 |
13 | {% block content %}
14 |
15 | {% for post in object_list %}
16 |
17 |
18 |
{{ post.publish|date:"Y F d" }}
19 |
{{ post.tease }}
20 |
21 | {% endfor %}
22 |
23 |
24 | {% if is_paginated %}
25 |
34 | {% endif %}
35 | {% endblock %}
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templatetags/.svn/entries:
--------------------------------------------------------------------------------
1 | 9
2 |
3 | dir
4 | 102
5 | http://django-basic-apps.googlecode.com/svn/trunk/blog/templatetags
6 | http://django-basic-apps.googlecode.com/svn
7 |
8 |
9 |
10 | 2008-10-15T16:18:25.512182Z
11 | 91
12 | nathan@playgroundblues.com
13 |
14 |
15 | svn:special svn:externals svn:needs-lock
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 5ae32e2a-df40-0410-a01d-45158a99d8df
28 |
29 | __init__.py
30 | file
31 |
32 |
33 |
34 |
35 | 2009-03-04T15:11:17.000000Z
36 | d41d8cd98f00b204e9800998ecf8427e
37 | 2008-03-27T00:51:14.650785Z
38 | 2
39 | nathan@playgroundblues.com
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | 0
62 |
63 | blog.py
64 | file
65 |
66 |
67 |
68 |
69 | 2009-03-04T15:11:17.000000Z
70 | 71575c6306716555116cfb9feb483816
71 | 2008-10-15T16:18:25.512182Z
72 | 91
73 | nathan@playgroundblues.com
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | 2771
96 |
97 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/datasets/blog_data.py:
--------------------------------------------------------------------------------
1 | from fixture import DataSet, DjangoFixture
2 | from blog.datasets.user_data import UserData
3 |
4 | class BlogMeta:
5 | django_app_label = 'blog'
6 |
7 | class CategoryData(DataSet):
8 | class Meta(BlogMeta):
9 | pass
10 | class python:
11 | title = 'python'
12 | slug = 'py'
13 | class testing:
14 | title = 'testing'
15 | slug = 'test'
16 |
17 | class PostData(DataSet):
18 | class Meta(BlogMeta):
19 | pass
20 | class first_post:
21 | title = "1st test post"
22 | body = "this one's about python"
23 | author = UserData.ben
24 | categories = [CategoryData.python]
25 | class second_post(first_post):
26 | title = "2nd test post"
27 | body = "this one's also about python"
28 | class third_post(first_post):
29 | title = "3rd test post"
30 | body = "this one's about both"
31 | categories = [CategoryData.python, CategoryData.testing]
32 |
--------------------------------------------------------------------------------
/fixture/examples/pylons_example/addressbook/addressbook/config/routing.py:
--------------------------------------------------------------------------------
1 | """Routes configuration
2 |
3 | The more specific and detailed routes should be defined first so they
4 | may take precedent over the more generic routes. For more information
5 | refer to the routes manual at http://routes.groovie.org/docs/
6 | """
7 | from pylons import config
8 | from routes import Mapper
9 |
10 | def make_map():
11 | """Create, configure and return the routes Mapper"""
12 | map = Mapper(directory=config['pylons.paths']['controllers'],
13 | always_scan=config['debug'])
14 | map.minimization = False
15 |
16 | # The ErrorController route (handles 404/500 error pages); it should
17 | # likely stay at the top, ensuring it can always be resolved
18 | map.connect('/error/{action}', controller='error')
19 | map.connect('/error/{action}/{id}', controller='error')
20 |
21 | # CUSTOM ROUTES HERE
22 | map.connect('/', controller='book', action='index')
23 |
24 | map.connect('/{controller}/{action}')
25 | map.connect('/{controller}/{action}/{id}')
26 |
27 | return map
28 |
--------------------------------------------------------------------------------
/fixture/examples/pylons_example/addressbook/addressbook/websetup.py:
--------------------------------------------------------------------------------
1 | """Setup the addressbook application"""
2 | import logging
3 |
4 | from addressbook.config.environment import load_environment
5 | from addressbook.model import meta
6 |
7 | from addressbook import model
8 | from fixture import SQLAlchemyFixture
9 | from fixture.style import NamedDataStyle
10 | from addressbook.datasets import PersonData
11 |
12 | log = logging.getLogger(__name__)
13 |
14 | def setup_app(command, conf, vars):
15 | """Place any commands to setup addressbook here"""
16 | load_environment(conf.global_conf, conf.local_conf)
17 |
18 | log.info("Creating tables")
19 | # Create the tables if they don't already exist
20 | meta.metadata.create_all(bind=meta.engine)
21 | log.info("Successfully setup")
22 |
23 | # load some initial data during setup-app :
24 |
25 | db = SQLAlchemyFixture(
26 | env=model, style=NamedDataStyle(),
27 | engine=meta.engine)
28 |
29 | data = db.data(PersonData)
30 | log.info("Inserting initial data")
31 | data.setup()
32 | log.info("Done")
33 |
34 |
--------------------------------------------------------------------------------
/fixture/examples/google_appengine_example/tests/datasets.py:
--------------------------------------------------------------------------------
1 |
2 | from fixture import DataSet
3 |
4 | __all__ = ['EntryData', 'CommentData']
5 |
6 | class EntryData(DataSet):
7 | class great_monday:
8 | title = "Monday Was Great"
9 | body = """\
10 | Monday was the best day ever. I got up (a little late, but that's OK) then I ground some coffee. Mmmm ... coffee! I love coffee. Do you know about Metropolis coffee? It's amazing. Delicious. I drank a beautiful cup of french pressed Spice Island, had a shave and went to work. What a day!
11 | """
12 |
13 | class CommentData(DataSet):
14 | class monday_liked_it:
15 | entry = EntryData.great_monday
16 | comment = """\
17 | I'm so glad you have a blog because I want to know what you are doing everyday. Heh, that sounds creepy. What I mean is it's so COOL that you had a great Monday. I like Mondays too.
18 | """
19 | class monday_sucked:
20 | entry = EntryData.great_monday
21 | comment = """\
22 | Are you serious? Mannnnnn, Monday really sucked.
23 | """
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templates/blog/post_search.html:
--------------------------------------------------------------------------------
1 | {% extends "blog/base_blog.html" %}
2 |
3 |
4 | {% block title %}Post search{% endblock %}
5 | {% block body_class %}{{ block.super }} post_search{% endblock %}
6 |
7 |
8 | {% block content_title %}
9 | Search
10 | {% endblock %}
11 |
12 |
13 | {% block content %}
14 |
20 |
21 | {% if message %}
22 | {{ message }}
23 | {% endif %}
24 |
25 | {% if object_list %}
26 |
27 | {% for post in object_list %}
28 |
29 |
30 |
{{ post.publish|date:"Y F d" }}
31 |
{{ post.tease }}
32 |
33 |
34 | {% endfor %}
35 |
36 | {% endif %}
37 | {% endblock %}
--------------------------------------------------------------------------------
/docs/source/api/fixture.dataset.rst:
--------------------------------------------------------------------------------
1 |
2 | ---------------
3 | fixture.dataset
4 | ---------------
5 |
6 | .. automodule:: fixture.dataset
7 |
8 | .. autoclass:: fixture.dataset.DataSet
9 | :show-inheritance:
10 | :members: __iter__, data, shared_instance
11 |
12 | .. autoclass:: fixture.dataset.DataSetMeta
13 | :show-inheritance:
14 | :members: storable, storable_name, primary_key
15 |
16 | .. autoclass:: fixture.dataset.SuperSet
17 | :show-inheritance:
18 | :members:
19 |
20 | .. autoclass:: fixture.dataset.MergedSuperSet
21 | :show-inheritance:
22 | :members:
23 |
24 | .. autoclass:: fixture.dataset.DataType
25 | :show-inheritance:
26 | :members: decorate_row
27 |
28 | .. autoclass:: fixture.dataset.DataRow
29 | :show-inheritance:
30 | :members:
31 |
32 | .. autoclass:: fixture.dataset.Ref
33 | :show-inheritance:
34 | :members: __call__
35 |
36 | .. autoclass:: fixture.dataset.RefValue
37 | :show-inheritance:
38 | :members:
39 |
40 | .. autoclass:: fixture.dataset.DataContainer
41 | :show-inheritance:
42 | :members:
43 |
44 | .. autoclass:: fixture.dataset.DataSetContainer
45 | :show-inheritance:
46 | :members:
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templates/blog/.svn/text-base/post_search.html.svn-base:
--------------------------------------------------------------------------------
1 | {% extends "blog/base_blog.html" %}
2 |
3 |
4 | {% block title %}Post search{% endblock %}
5 | {% block body_class %}{{ block.super }} post_search{% endblock %}
6 |
7 |
8 | {% block content_title %}
9 | Search
10 | {% endblock %}
11 |
12 |
13 | {% block content %}
14 |
20 |
21 | {% if message %}
22 | {{ message }}
23 | {% endif %}
24 |
25 | {% if object_list %}
26 |
27 | {% for post in object_list %}
28 |
29 |
30 |
{{ post.publish|date:"Y F d" }}
31 |
{{ post.tease }}
32 |
33 |
34 | {% endfor %}
35 |
36 | {% endif %}
37 | {% endblock %}
--------------------------------------------------------------------------------
/fixture/examples/pylons_example/addressbook/setup.py:
--------------------------------------------------------------------------------
1 | try:
2 | from setuptools import setup, find_packages
3 | except ImportError:
4 | from ez_setup import use_setuptools
5 | use_setuptools()
6 | from setuptools import setup, find_packages
7 |
8 | setup(
9 | name='addressbook',
10 | version='0.1',
11 | description='',
12 | author='',
13 | author_email='',
14 | url='',
15 | install_requires=[
16 | "Routes==1.10.3",
17 | "Pylons==0.9.7",
18 | "SQLAlchemy==0.4.8",
19 | ],
20 | setup_requires=["PasteScript>=1.6.3"],
21 | packages=find_packages(exclude=['ez_setup']),
22 | include_package_data=True,
23 | test_suite='nose.collector',
24 | package_data={'addressbook': ['i18n/*/LC_MESSAGES/*.mo']},
25 | #message_extractors={'addressbook': [
26 | # ('**.py', 'python', None),
27 | # ('templates/**.mako', 'mako', {'input_encoding': 'utf-8'}),
28 | # ('public/**', 'ignore', None)]},
29 | zip_safe=False,
30 | paster_plugins=['PasteScript', 'Pylons'],
31 | entry_points="""
32 | [paste.app_factory]
33 | main = addressbook.config.middleware:make_app
34 |
35 | [paste.app_install]
36 | main = pylons.util:PylonsInstaller
37 | """,
38 | )
39 |
--------------------------------------------------------------------------------
/fixture/test/test_loadable/test_django/test_wrong_declarations.py:
--------------------------------------------------------------------------------
1 | from fixture import DjangoFixture, DataSet, style
2 | from fixture.exc import LoadError
3 | from nose.tools import raises, assert_raises
4 |
5 | from util import *
6 | from fixture.examples.django_example.app import models
7 |
8 | class ReviewerData(DataSet):
9 | class ben:
10 | name = 'ben'
11 |
12 | class BookData(DataSet):
13 | class dune:
14 | title = "Dune"
15 | reviewers = [ReviewerData.ben]
16 |
17 | class AuthorData(DataSet):
18 | class frank_herbert:
19 | first_name = "Frank"
20 | last_name = "Herbert"
21 | books = BookData.dune
22 |
23 | dj_fixture = DjangoFixture(env=models, style=style.NamedDataStyle())
24 |
25 |
26 | def test_wrong_relation_declaration():
27 | assert 'reviewers' in models.Book._meta.get_all_field_names()
28 | data = dj_fixture.data(BookData)
29 | assert_raises(LoadError, data.setup)
30 | data.teardown()
31 |
32 | def test_invalid_m2m():
33 | class ReviewerData(DataSet):
34 | class ben:
35 | name = 'ben'
36 | reviewed = [BookData.dune, AuthorData.frank_herbert]
37 | assert_empty(models)
38 | data = dj_fixture.data(ReviewerData)
39 | assert_raises(LoadError, data.setup)
40 | data.teardown()
41 |
42 |
--------------------------------------------------------------------------------
/fixture/examples/pylons_example/addressbook/addressbook.egg-info/SOURCES.txt:
--------------------------------------------------------------------------------
1 | MANIFEST.in
2 | README.txt
3 | setup.cfg
4 | setup.py
5 | addressbook/__init__.py
6 | addressbook/websetup.py
7 | addressbook.egg-info/PKG-INFO
8 | addressbook.egg-info/SOURCES.txt
9 | addressbook.egg-info/dependency_links.txt
10 | addressbook.egg-info/entry_points.txt
11 | addressbook.egg-info/not-zip-safe
12 | addressbook.egg-info/paster_plugins.txt
13 | addressbook.egg-info/requires.txt
14 | addressbook.egg-info/top_level.txt
15 | addressbook/config/__init__.py
16 | addressbook/config/deployment.ini_tmpl
17 | addressbook/config/environment.py
18 | addressbook/config/middleware.py
19 | addressbook/config/routing.py
20 | addressbook/controllers/__init__.py
21 | addressbook/controllers/book.py
22 | addressbook/controllers/error.py
23 | addressbook/datasets/__init__.py
24 | addressbook/lib/__init__.py
25 | addressbook/lib/app_globals.py
26 | addressbook/lib/base.py
27 | addressbook/lib/helpers.py
28 | addressbook/model/__init__.py
29 | addressbook/model/meta.py
30 | addressbook/public/bg.png
31 | addressbook/public/favicon.ico
32 | addressbook/public/pylons-logo.gif
33 | addressbook/templates/book.mako
34 | addressbook/tests/__init__.py
35 | addressbook/tests/test_models.py
36 | addressbook/tests/functional/__init__.py
37 | addressbook/tests/functional/test_book.py
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/.svn/text-base/urls.py.svn-base:
--------------------------------------------------------------------------------
1 | from django.conf.urls.defaults import *
2 | from basic.blog import views as blog_views
3 |
4 |
5 | urlpatterns = patterns('',
6 | url(r'^(?P\d{4})/(?P\w{3})/(?P\d{1,2})/(?P[-\w]+)/$',
7 | view=blog_views.post_detail,
8 | name='blog_detail'),
9 |
10 | url(r'^(?P\d{4})/(?P\w{3})/(?P\d{1,2})/$',
11 | view=blog_views.post_archive_day,
12 | name='blog_archive_day'),
13 |
14 | url(r'^(?P\d{4})/(?P\w{3})/$',
15 | view=blog_views.post_archive_month,
16 | name='blog_archive_month'),
17 |
18 | url(r'^(?P\d{4})/$',
19 | view=blog_views.post_archive_year,
20 | name='blog_archive_year'),
21 |
22 | url(r'^categories/(?P[-\w]+)/$',
23 | view=blog_views.category_detail,
24 | name='blog_category_detail'),
25 |
26 | url (r'^categories/$',
27 | view=blog_views.category_list,
28 | name='blog_category_list'),
29 |
30 | url (r'^search/$',
31 | view=blog_views.search,
32 | name='blog_search'),
33 |
34 | url(r'^page/(?P\w)/$',
35 | view=blog_views.post_list,
36 | name='blog_index_paginated'),
37 |
38 | url(r'^$',
39 | view=blog_views.post_list,
40 | name='blog_index'),
41 | )
--------------------------------------------------------------------------------
/fixture/examples/pylons_example/addressbook/addressbook/model/__init__.py:
--------------------------------------------------------------------------------
1 | """The application's model objects"""
2 | import sqlalchemy as sa
3 | from sqlalchemy import orm
4 |
5 | from addressbook.model import meta
6 |
7 | def init_model(engine):
8 | """Call me before using any of the tables or classes in the model"""
9 | meta.Session.configure(bind=engine)
10 | meta.engine = engine
11 |
12 | t_people = sa.Table('people', meta.metadata,
13 | sa.Column('id', sa.types.Integer, primary_key=True),
14 | sa.Column('name', sa.types.String(100)),
15 | sa.Column('email', sa.types.String(100))
16 | )
17 |
18 | t_addresses_people = sa.Table('addresses_people', meta.metadata,
19 | sa.Column('id', sa.types.Integer, primary_key=True),
20 | sa.Column('person_id', sa.types.Integer, sa.ForeignKey('people.id')),
21 | sa.Column('address_id', sa.types.Integer, sa.ForeignKey('addresses.id'))
22 | )
23 |
24 | t_addresses = sa.Table('addresses', meta.metadata,
25 | sa.Column('id', sa.types.Integer, primary_key=True),
26 | sa.Column('address', sa.types.String(100))
27 | )
28 |
29 | class Person(object):
30 | pass
31 |
32 | class Address(object):
33 | pass
34 |
35 | orm.mapper(Address, t_addresses)
36 | orm.mapper(Person, t_people, properties = {
37 | 'my_addresses' : orm.relation(Address, secondary = t_addresses_people),
38 | })
39 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls.defaults import *
2 | from fixture.examples.django_example.blog import views as blog_views
3 |
4 |
5 | urlpatterns = patterns('',
6 | url(r'^(?P\d{4})/(?P\w{3})/(?P\d{1,2})/(?P[-\w]+)/$',
7 | view=blog_views.post_detail,
8 | name='blog_detail'),
9 |
10 | url(r'^(?P\d{4})/(?P\w{3})/(?P\d{1,2})/$',
11 | view=blog_views.post_archive_day,
12 | name='blog_archive_day'),
13 |
14 | url(r'^(?P\d{4})/(?P\w{3})/$',
15 | view=blog_views.post_archive_month,
16 | name='blog_archive_month'),
17 |
18 | url(r'^(?P\d{4})/$',
19 | view=blog_views.post_archive_year,
20 | name='blog_archive_year'),
21 |
22 | url(r'^categories/(?P[-\w]+)/$',
23 | view=blog_views.category_detail,
24 | name='blog_category_detail'),
25 |
26 | url (r'^categories/$',
27 | view=blog_views.category_list,
28 | name='blog_category_list'),
29 |
30 | url (r'^search/$',
31 | view=blog_views.search,
32 | name='blog_search'),
33 |
34 | url(r'^page/(?P\w)/$',
35 | view=blog_views.post_list,
36 | name='blog_index_paginated'),
37 |
38 | url(r'^$',
39 | view=blog_views.post_list,
40 | name='blog_index'),
41 | )
--------------------------------------------------------------------------------
/fixture/setup_cmd/apidocs.py:
--------------------------------------------------------------------------------
1 | from distutils.cmd import Command
2 | import os, sys, shutil
3 | from os import path
4 | import optparse
5 | from fixture import docs
6 | from fixture.test import teardown_examples
7 | from docutils.core import (
8 | publish_file, publish_string, publish_doctree, publish_from_doctree)
9 |
10 |
11 | class apidocs(Command):
12 | description = "create API documentation"
13 | user_options = [
14 | # ('optname=', None, ""),
15 | ]
16 | # boolean_options = ['update']
17 |
18 | def initialize_options(self):
19 | pass
20 |
21 | def finalize_options(self):
22 | pass
23 |
24 | def run(self):
25 | """build API documentation."""
26 |
27 | # if options.build_dir:
28 | # docs.builddir = options.build_dir
29 | if not path.exists(docs.builddir):
30 | os.mkdir(docs.builddir)
31 | docs.state_is_api = True
32 | from pydoctor.driver import main
33 | argv = [
34 | '--html-output=%s/apidocs' % docs.builddir, '--project-name=fixture',
35 | '--docformat=restructuredtext',
36 | '--project-url=http://code.google.com/p/fixture/', '--make-html',
37 | '--add-package=fixture', '--verbose', '--verbose']
38 |
39 | sys.argv[0] = ['pydoctor'] # can't remember why
40 | main(argv)
--------------------------------------------------------------------------------
/fixture/__init__.py:
--------------------------------------------------------------------------------
1 |
2 | """fixture is a python module for loading and referencing test data
3 |
4 | It provides several utilities for achieving a *fixed state* when testing
5 | Python programs. Specifically, these utilities setup / teardown databases and
6 | work with temporary file systems.
7 |
8 | You may want to start by reading the `End User Documentation`_.
9 |
10 | .. _End User Documentation: http://farmdev.com/projects/fixture/docs/
11 |
12 | If you are reading this from a `source checkout`_ then you may want to build the documentation locally. Install `Sphinx`_ then run::
13 |
14 | cd /path/to/fixture/source
15 | cd docs
16 | make html
17 |
18 | Then open ``build/html/index.html`` in your web browser. If that fails, you can read the reST files starting at ``docs/source/index.rst``
19 |
20 | .. _source checkout: http://fixture.googlecode.com/hg/#egg=fixture-dev
21 | .. _Sphinx: http://sphinx.pocoo.org/
22 |
23 | """
24 |
25 | __version__ = "1.4"
26 |
27 | import logging
28 | import sys
29 |
30 | from fixture.loadable import *
31 | from fixture.dataset import *
32 | from fixture.util import *
33 | from fixture.io import *
34 | from fixture.style import *
35 |
36 | def setup_test_not_supported():
37 | """hook for setup for the test command."""
38 | raise NotImplementedError("use: `python setup.py nosetests` instead")
39 | setup_test_not_supported.__test__ = False
40 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/.svn/all-wcprops:
--------------------------------------------------------------------------------
1 | K 25
2 | svn:wc:ra_dav:version-url
3 | V 28
4 | /svn/!svn/ver/100/trunk/blog
5 | END
6 | admin.py
7 | K 25
8 | svn:wc:ra_dav:version-url
9 | V 36
10 | /svn/!svn/ver/54/trunk/blog/admin.py
11 | END
12 | views.py
13 | K 25
14 | svn:wc:ra_dav:version-url
15 | V 36
16 | /svn/!svn/ver/92/trunk/blog/views.py
17 | END
18 | managers.py
19 | K 25
20 | svn:wc:ra_dav:version-url
21 | V 39
22 | /svn/!svn/ver/91/trunk/blog/managers.py
23 | END
24 | __init__.py
25 | K 25
26 | svn:wc:ra_dav:version-url
27 | V 38
28 | /svn/!svn/ver/2/trunk/blog/__init__.py
29 | END
30 | CHANGELOG.yml
31 | K 25
32 | svn:wc:ra_dav:version-url
33 | V 41
34 | /svn/!svn/ver/70/trunk/blog/CHANGELOG.yml
35 | END
36 | sitemap.py
37 | K 25
38 | svn:wc:ra_dav:version-url
39 | V 38
40 | /svn/!svn/ver/39/trunk/blog/sitemap.py
41 | END
42 | tests.py
43 | K 25
44 | svn:wc:ra_dav:version-url
45 | V 36
46 | /svn/!svn/ver/94/trunk/blog/tests.py
47 | END
48 | models.py
49 | K 25
50 | svn:wc:ra_dav:version-url
51 | V 37
52 | /svn/!svn/ver/63/trunk/blog/models.py
53 | END
54 | README.txt
55 | K 25
56 | svn:wc:ra_dav:version-url
57 | V 39
58 | /svn/!svn/ver/100/trunk/blog/README.txt
59 | END
60 | urls.py
61 | K 25
62 | svn:wc:ra_dav:version-url
63 | V 35
64 | /svn/!svn/ver/70/trunk/blog/urls.py
65 | END
66 | feeds.py
67 | K 25
68 | svn:wc:ra_dav:version-url
69 | V 36
70 | /svn/!svn/ver/50/trunk/blog/feeds.py
71 | END
72 |
--------------------------------------------------------------------------------
/fixture/examples/db/sqlobject_examples.py:
--------------------------------------------------------------------------------
1 |
2 | """examples for using SQLObject fixtures."""
3 |
4 | try:
5 | import sqlobject
6 | except ImportError:
7 | sqlobject = None
8 |
9 | Category, Product, Offer = None, None, None
10 |
11 | if sqlobject:
12 | from sqlobject import *
13 |
14 | class Category(SQLObject):
15 | class sqlmeta:
16 | table = 'fixture_sqlobject_category'
17 | name = StringCol()
18 |
19 | class Product(SQLObject):
20 | class sqlmeta:
21 | table = 'fixture_sqlobject_product'
22 | name = StringCol()
23 | category = ForeignKey('Category')
24 |
25 | class Offer(SQLObject):
26 | class sqlmeta:
27 | table = 'fixture_sqlobject_offer'
28 | name = StringCol()
29 | category = ForeignKey('Category')
30 | product = ForeignKey('Product')
31 |
32 | def setup_db(conn):
33 | assert conn is not None
34 | Category.createTable(connection=conn)
35 | Product.createTable(connection=conn)
36 | Offer.createTable(connection=conn)
37 |
38 | def teardown_db(conn):
39 | assert conn is not None
40 |
41 | ## apparently, this causes a deadlock if *all* sqlobject
42 | ## interaction is not inside a transaction. excellent!
43 | ## as a workaround, loader's accept use_transaction = True
44 | for tb in (Offer, Product, Category):
45 | tb.dropTable(connection=conn)
46 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/.svn/text-base/feeds.py.svn-base:
--------------------------------------------------------------------------------
1 | from django.contrib.syndication.feeds import FeedDoesNotExist
2 | from django.core.exceptions import ObjectDoesNotExist
3 | from django.contrib.sites.models import Site
4 | from django.contrib.syndication.feeds import Feed
5 | from django.core.urlresolvers import reverse
6 | from basic.blog.models import Post, Category
7 |
8 |
9 | class BlogPostsFeed(Feed):
10 | _site = Site.objects.get_current()
11 | title = '%s feed' % _site.name
12 | description = '%s posts feed.' % _site.name
13 |
14 | def link(self):
15 | return reverse('blog_index')
16 |
17 | def items(self):
18 | return Post.objects.published()[:10]
19 |
20 | def item_pubdate(self, obj):
21 | return obj.publish
22 |
23 |
24 | class BlogPostsByCategory(Feed):
25 | _site = Site.objects.get_current()
26 | title = '%s posts category feed' % _site.name
27 |
28 | def get_object(self, bits):
29 | if len(bits) != 1:
30 | raise ObjectDoesNotExist
31 | return Category.objects.get(slug__exact=bits[0])
32 |
33 | def link(self, obj):
34 | if not obj:
35 | raise FeedDoesNotExist
36 | return obj.get_absolute_url()
37 |
38 | def description(self, obj):
39 | return "Posts recently categorized as %s" % obj.title
40 |
41 | def items(self, obj):
42 | return obj.post_set.published()[:10]
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templates/blog/.svn/all-wcprops:
--------------------------------------------------------------------------------
1 | K 25
2 | svn:wc:ra_dav:version-url
3 | V 42
4 | /svn/!svn/ver/83/trunk/blog/templates/blog
5 | END
6 | base_blog.html
7 | K 25
8 | svn:wc:ra_dav:version-url
9 | V 57
10 | /svn/!svn/ver/32/trunk/blog/templates/blog/base_blog.html
11 | END
12 | category_detail.html
13 | K 25
14 | svn:wc:ra_dav:version-url
15 | V 63
16 | /svn/!svn/ver/83/trunk/blog/templates/blog/category_detail.html
17 | END
18 | post_list.html
19 | K 25
20 | svn:wc:ra_dav:version-url
21 | V 57
22 | /svn/!svn/ver/83/trunk/blog/templates/blog/post_list.html
23 | END
24 | post_archive_day.html
25 | K 25
26 | svn:wc:ra_dav:version-url
27 | V 64
28 | /svn/!svn/ver/83/trunk/blog/templates/blog/post_archive_day.html
29 | END
30 | post_archive_year.html
31 | K 25
32 | svn:wc:ra_dav:version-url
33 | V 65
34 | /svn/!svn/ver/83/trunk/blog/templates/blog/post_archive_year.html
35 | END
36 | post_detail.html
37 | K 25
38 | svn:wc:ra_dav:version-url
39 | V 59
40 | /svn/!svn/ver/83/trunk/blog/templates/blog/post_detail.html
41 | END
42 | category_list.html
43 | K 25
44 | svn:wc:ra_dav:version-url
45 | V 61
46 | /svn/!svn/ver/83/trunk/blog/templates/blog/category_list.html
47 | END
48 | post_search.html
49 | K 25
50 | svn:wc:ra_dav:version-url
51 | V 59
52 | /svn/!svn/ver/83/trunk/blog/templates/blog/post_search.html
53 | END
54 | post_archive_month.html
55 | K 25
56 | svn:wc:ra_dav:version-url
57 | V 66
58 | /svn/!svn/ver/83/trunk/blog/templates/blog/post_archive_month.html
59 | END
60 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/tests.py:
--------------------------------------------------------------------------------
1 |
2 | from fixture import DataSet, DjangoFixture
3 | from fixture.style import NamedDataStyle
4 | from fixture.django_testcase import FixtureTestCase
5 | from datetime import datetime
6 | from django.contrib.auth.models import User
7 | from fixture.examples.django_example.blog.models import Post, Category
8 | from fixture.examples.django_example.blog.datasets.blog_data import (
9 | UserData, PostData, CategoryData)
10 |
11 | db_fixture = DjangoFixture(style=NamedDataStyle())
12 |
13 | class TestBlogWithData(FixtureTestCase):
14 | fixture = db_fixture
15 | datasets = [PostData]
16 |
17 | def test_blog_posts(self):
18 | self.assertEquals(Post.objects.all().count(), 3,
19 | "There are 3 blog posts")
20 | post = Post.objects.get(title=PostData.third_post.title)
21 | self.assertEquals(post.categories.count(), 2,
22 | "The 3rd test post is in 2 categories")
23 |
24 | def test_posts_by_category(self):
25 | py = Category.objects.get(title=CategoryData.python.title)
26 | self.assertEquals(py.post_set.count(), 3,
27 | "There are 3 posts in python category")
28 |
29 | def test_posts_by_author(self):
30 | ben = User.objects.get(username=UserData.ben.username)
31 | self.assertEquals(ben.post_set.all().count(), 3,
32 | "Ben has published 3 posts")
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/fixture/test/test_loadable/test_django/fixtures.py:
--------------------------------------------------------------------------------
1 | from fixture import DataSet, style
2 |
3 | class ValidNoRelationsData(DataSet):
4 | class one:
5 | char = "one"
6 | num = 1
7 | class two:
8 | char = "two"
9 | num = 2
10 |
11 | class InvalidNoRelationsData(DataSet):
12 | class one:
13 | char = "one"
14 | invalid = 'test'
15 | class two:
16 | char = "two"
17 | some_other = 2
18 |
19 | class AuthorData(DataSet):
20 | class Meta:
21 | django_model = 'app.Author'
22 | class frank_herbert:
23 | first_name = "Frank"
24 | last_name = "Herbert"
25 | class guido:
26 | first_name = "Guido"
27 | last_name = "Van rossum"
28 |
29 | class BookData(DataSet):
30 | class Meta:
31 | django_model = 'app.Book'
32 | class dune:
33 | title = "Dune"
34 | author = AuthorData.frank_herbert
35 |
36 | class python:
37 | title = 'Python'
38 | author = AuthorData.guido
39 |
40 | class ReviewerData(DataSet):
41 | class Meta:
42 | django_model = 'app.Reviewer'
43 | class ben:
44 | name = 'ben'
45 | reviewed = [BookData.dune, BookData.python]
46 |
47 | class DjangoDataSetWithMeta(DataSet):
48 | class Meta:
49 | django_model = 'app.Author'
50 | class frank_herbert:
51 | first_name = "Frank"
52 | last_name = "Herbert"
53 | class guido:
54 | first_name = "Guido"
55 | last_name = "Van rossum"
--------------------------------------------------------------------------------
/fixture/test/test_loadable/test_django/test_loading.py:
--------------------------------------------------------------------------------
1 |
2 | from fixture import DjangoFixture
3 | from fixture import DataSet, style
4 |
5 | from fixture.examples.django_example.app import models
6 | from fixtures import *
7 | from util import *
8 |
9 | dj_fixture = DjangoFixture()
10 |
11 | def test_fk_rels():
12 | assert_empty(models)
13 | data = dj_fixture.data(AuthorData, BookData)
14 | try:
15 | data.setup()
16 | assert models.Author.objects.get(first_name='Frank').books.count() == 1
17 | finally:
18 | data.teardown()
19 | assert_empty(models)
20 |
21 | def test_m2m():
22 | assert_empty(models)
23 | data = dj_fixture.data(AuthorData, BookData, ReviewerData)
24 | try:
25 | data.setup()
26 | ben = models.Reviewer.objects.all()[0]
27 | # Reviewed have been added as a list
28 | assert ben.reviewed.count() == 2
29 | dune = models.Book.objects.get(title='Dune')
30 | # Reverse relations work
31 | assert ben in dune.reviewers.all()
32 | # A single object passed to a many to many also works
33 | frank = models.Author.objects.get(first_name='Frank')
34 | assert frank.books.count() == 1
35 | assert dune in frank.books.all()
36 | finally:
37 | data.teardown()
38 | assert_empty(models)
39 |
40 | def test_dataset_with_meta():
41 | assert_empty(models)
42 | data = dj_fixture.data(DjangoDataSetWithMeta)
43 | try:
44 | data.setup()
45 | assert models.Author.objects.count() == 2
46 | finally:
47 | data.teardown()
48 | assert_empty(models)
49 |
--------------------------------------------------------------------------------
/fixture/examples/pylons_example/addressbook/addressbook/config/deployment.ini_tmpl:
--------------------------------------------------------------------------------
1 | #
2 | # addressbook - Pylons configuration
3 | #
4 | # The %(here)s variable will be replaced with the parent directory of this file
5 | #
6 | [DEFAULT]
7 | debug = true
8 | email_to = you@yourdomain.com
9 | smtp_server = localhost
10 | error_email_from = paste@localhost
11 |
12 | [server:main]
13 | use = egg:Paste#http
14 | host = 0.0.0.0
15 | port = 5000
16 |
17 | [app:main]
18 | use = egg:addressbook
19 | full_stack = true
20 | static_files = true
21 |
22 | cache_dir = %(here)s/data
23 | beaker.session.key = addressbook
24 | beaker.session.secret = ${app_instance_secret}
25 | app_instance_uuid = ${app_instance_uuid}
26 |
27 | # If you'd like to fine-tune the individual locations of the cache data dirs
28 | # for the Cache data, or the Session saves, un-comment the desired settings
29 | # here:
30 | #beaker.cache.data_dir = %(here)s/data/cache
31 | #beaker.session.data_dir = %(here)s/data/sessions
32 |
33 | # SQLAlchemy database URL
34 | sqlalchemy.url = sqlite:///production.db
35 |
36 | # WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*
37 | # Debug mode will enable the interactive debugging tool, allowing ANYONE to
38 | # execute malicious code after an exception is raised.
39 | set debug = false
40 |
41 |
42 | # Logging configuration
43 | [loggers]
44 | keys = root
45 |
46 | [handlers]
47 | keys = console
48 |
49 | [formatters]
50 | keys = generic
51 |
52 | [logger_root]
53 | level = INFO
54 | handlers = console
55 |
56 | [handler_console]
57 | class = StreamHandler
58 | args = (sys.stderr,)
59 | level = NOTSET
60 | formatter = generic
61 |
62 | [formatter_generic]
63 | format = %(asctime)s %(levelname)-5.5s [%(name)s] %(message)s
64 |
--------------------------------------------------------------------------------
/fixture/exc.py:
--------------------------------------------------------------------------------
1 |
2 | """Fixture exceptions"""
3 |
4 | class UninitializedError(Exception):
5 | pass
6 |
7 | class DataSetActionException(Exception):
8 | """
9 | An exception while performing some action with a DataSet.
10 |
11 | In addtion to ``etype`` and ``val`` adds these properties:
12 |
13 | ``dataset``
14 | :class:`DataSet ` that caused the exception
15 |
16 | ``key``
17 | Key on DataSet row if there is one
18 |
19 | ``row``
20 | :class:`DataRow ` if there is one
21 |
22 | ``stored_object``
23 | Stored object if there is one
24 |
25 | used by :mod:`fixture.loadable` classes
26 | """
27 | def __init__(self, etype, val, dataset,
28 | key=None, row=None, stored_object=None):
29 | msg = "in %s" % dataset
30 | if key or row:
31 | msg = "with '%s' of '%s' %s" % (key, row, msg)
32 | elif stored_object:
33 | msg = "with %s %s" % (stored_object, msg)
34 |
35 | Exception.__init__(self, "%s: %s (%s)" % (etype.__name__, val, msg))
36 |
37 | class LoadError(DataSetActionException):
38 | """
39 | An exception while loading data in DataSet.
40 |
41 | used by :mod:`fixture.loadable` classes
42 | """
43 | pass
44 | class UnloadError(DataSetActionException):
45 | """
46 | An exception while unloading data from a DataSet.
47 |
48 | used by :mod:`fixture.loadable` classes
49 | """
50 | pass
51 |
52 | class StorageMediaNotFound(LookupError):
53 | """
54 | Looking up a storable object failed.
55 |
56 | used by :mod:`fixture.loadable` classes
57 | """
58 | pass
--------------------------------------------------------------------------------
/fixture/setup_cmd/pushdocs.py:
--------------------------------------------------------------------------------
1 |
2 | import os
3 | from distutils.cmd import Command
4 | from fixture import docs
5 |
6 | class pushdocs(Command):
7 | description = "push documentation to server"
8 | user_options = [
9 | # ('optname=', None, ""),
10 | ]
11 | # boolean_options = ['update']
12 |
13 | def initialize_options(self):
14 | pass
15 |
16 | def finalize_options(self):
17 | pass
18 |
19 | def run(self):
20 | assert 'FD_HOST' in os.environ, (
21 | "environment variable $FD_HOST must be set with the server "
22 | "host to connect to")
23 | assert os.path.exists(docs.builddir), (
24 | "first run python setup.py userdocs apidocs")
25 | apidocs = os.path.join(docs.builddir, 'apidocs')
26 | assert os.path.exists(apidocs), (
27 | "first run python setup.py apidocs")
28 | userdocs = os.path.join(docs.builddir, 'docs')
29 | assert os.path.exists(userdocs), (
30 | "first run python setup.py userdocs")
31 | def push_pkg(pkg_path):
32 | os.chdir(os.path.dirname(pkg_path))
33 | pkg = os.path.basename(pkg_path)
34 | os.system("rm %s.tgz" % pkg)
35 | os.system("tar -czf %s.tgz %s" % (pkg,pkg))
36 | os.system("scp %s.tgz %s:~/app/static/farmdev/projects/fixture/" % (
37 | pkg, os.environ['FD_HOST']))
38 | os.system(
39 | "ssh %s 'cd ~/app/static/farmdev/projects/fixture; "
40 | "tar -xzf %s.tgz && rm %s.tgz'" % (
41 | os.environ['FD_HOST'], pkg, pkg))
42 | print "pushed %s to %s" % (pkg, os.environ['FD_HOST'])
43 | push_pkg(apidocs)
44 | push_pkg(userdocs)
--------------------------------------------------------------------------------
/fixture/examples/pylons_example/addressbook/addressbook/controllers/error.py:
--------------------------------------------------------------------------------
1 | import cgi
2 |
3 | from paste.urlparser import PkgResourcesParser
4 | from pylons import request
5 | from pylons.controllers.util import forward
6 | from pylons.middleware import error_document_template
7 | from webhelpers.html.builder import literal
8 |
9 | from addressbook.lib.base import BaseController
10 |
11 | class ErrorController(BaseController):
12 |
13 | """Generates error documents as and when they are required.
14 |
15 | The ErrorDocuments middleware forwards to ErrorController when error
16 | related status codes are returned from the application.
17 |
18 | This behaviour can be altered by changing the parameters to the
19 | ErrorDocuments middleware in your config/middleware.py file.
20 |
21 | """
22 |
23 | def document(self):
24 | """Render the error document"""
25 | resp = request.environ.get('pylons.original_response')
26 | content = literal(resp.body) or cgi.escape(request.GET.get('message', ''))
27 | page = error_document_template % \
28 | dict(prefix=request.environ.get('SCRIPT_NAME', ''),
29 | code=cgi.escape(request.GET.get('code', str(resp.status_int))),
30 | message=content)
31 | return page
32 |
33 | def img(self, id):
34 | """Serve Pylons' stock images"""
35 | return self._serve_file('/'.join(['media/img', id]))
36 |
37 | def style(self, id):
38 | """Serve Pylons' stock stylesheets"""
39 | return self._serve_file('/'.join(['media/style', id]))
40 |
41 | def _serve_file(self, path):
42 | """Call Paste's FileApp (a WSGI application) to serve the file
43 | at the specified path
44 | """
45 | request.environ['PATH_INFO'] = '/%s' % path
46 | return forward(PkgResourcesParser('pylons', 'pylons'))
47 |
--------------------------------------------------------------------------------
/fixture/examples/pylons_example/addressbook/addressbook/config/environment.py:
--------------------------------------------------------------------------------
1 | """Pylons environment configuration"""
2 | import os
3 |
4 | from mako.lookup import TemplateLookup
5 | from pylons import config
6 | from pylons.error import handle_mako_error
7 | from sqlalchemy import engine_from_config
8 |
9 | import addressbook.lib.app_globals as app_globals
10 | import addressbook.lib.helpers
11 | from addressbook.config.routing import make_map
12 | from addressbook.model import init_model
13 |
14 | def load_environment(global_conf, app_conf):
15 | """Configure the Pylons environment via the ``pylons.config``
16 | object
17 | """
18 | # Pylons paths
19 | root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
20 | paths = dict(root=root,
21 | controllers=os.path.join(root, 'controllers'),
22 | static_files=os.path.join(root, 'public'),
23 | templates=[os.path.join(root, 'templates')])
24 |
25 | # Initialize config with the basic options
26 | config.init_app(global_conf, app_conf, package='addressbook', paths=paths)
27 |
28 | config['routes.map'] = make_map()
29 | config['pylons.app_globals'] = app_globals.Globals()
30 | config['pylons.h'] = addressbook.lib.helpers
31 |
32 | # Create the Mako TemplateLookup, with the default auto-escaping
33 | config['pylons.app_globals'].mako_lookup = TemplateLookup(
34 | directories=paths['templates'],
35 | error_handler=handle_mako_error,
36 | module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
37 | input_encoding='utf-8', default_filters=['escape'],
38 | imports=['from webhelpers.html import escape'])
39 |
40 | # Setup the SQLAlchemy database engine
41 | engine = engine_from_config(config, 'sqlalchemy.')
42 | init_model(engine)
43 |
44 | # CONFIGURATION OPTIONS HERE (note: all config options will override
45 | # any Pylons config options)
46 |
--------------------------------------------------------------------------------
/docs/source/using-temp-io.rst:
--------------------------------------------------------------------------------
1 |
2 | .. _using-temp-io:
3 |
4 | -------------------------------
5 | TempIO: A Temporary File System
6 | -------------------------------
7 |
8 | This object is useful for tests that need to set up a directory structure
9 | and work with files and paths. Once you instantiate it, you have a temporary
10 | directory that will self-destruct when it falls out of scope:
11 |
12 | .. doctest::
13 |
14 | >>> from fixture import TempIO
15 | >>> tmp = TempIO()
16 | >>> tmp #doctest: +ELLIPSIS
17 | '/.../tmp_fixture...'
18 |
19 | Add sub-directories by simply assigning an attribute the basename of the new
20 | subdirectory, like so:
21 |
22 | .. doctest::
23 |
24 | >>> tmp.incoming = "incoming"
25 | >>> import os
26 | >>> os.path.exists(tmp.incoming)
27 | True
28 |
29 | The new attribute is now an absolute path to a subdirectory, "incoming", of
30 | the tmp root, as well as an object itself. Note that tmp and tmp.incoming are
31 | just string objects, but with several os.path methods mixed in for convenience.
32 | See the :class:`fixture.io.DeletableDirPath` API for details. However, you can pass it to other objects and
33 | it will represent itself as its absolute path.
34 |
35 | Putting Files
36 | -------------
37 |
38 | You can also insert files to the directory with putfile():
39 |
40 | .. doctest::
41 |
42 | >>> foopath = tmp.incoming.putfile("foo.txt", "contents of foo")
43 | >>> tmp.incoming.join("foo.txt").exists()
44 | True
45 |
46 | Removing The Temp Dir
47 | ---------------------
48 |
49 | The directory root will self-destruct when it goes out of scope or ``atexit``.
50 | You can explicitly delete the object at your test's teardown if you like:
51 |
52 | .. doctest::
53 |
54 | >>> tmpdir = str(tmp) # copy the directory path
55 | >>> del tmp
56 | >>> os.path.exists(tmpdir)
57 | False
58 |
59 | API Documentation
60 | -----------------
61 |
62 | - :mod:`fixture.io`
63 |
64 | .. _DirPath: ../apidocs/fixture.io.DirPath.html
--------------------------------------------------------------------------------
/setup_test_buildout.py:
--------------------------------------------------------------------------------
1 | ##############################################################################
2 | #
3 | # Copyright (c) 2006 Zope Corporation and Contributors.
4 | # All Rights Reserved.
5 | #
6 | # This software is subject to the provisions of the Zope Public License,
7 | # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
8 | # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
9 | # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10 | # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
11 | # FOR A PARTICULAR PURPOSE.
12 | #
13 | ##############################################################################
14 | """Bootstrap a buildout-based project
15 |
16 | Simply run this script in a directory containing a buildout.cfg.
17 | The script accepts buildout command-line options, so you can
18 | use the -c option to specify an alternate configuration file.
19 |
20 | $Id: bootstrap.py 85041 2008-03-31 15:57:30Z andreasjung $
21 | """
22 |
23 | import os, shutil, sys, tempfile, urllib2
24 |
25 | tmpeggs = tempfile.mkdtemp()
26 |
27 | try:
28 | import pkg_resources
29 | except ImportError:
30 | ez = {}
31 | exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
32 | ).read() in ez
33 | ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
34 |
35 | import pkg_resources
36 |
37 | if sys.platform == 'win32':
38 | def quote(c):
39 | if ' ' in c:
40 | return '"%s"' % c # work around spawn lamosity on windows
41 | else:
42 | return c
43 | else:
44 | def quote (c):
45 | return c
46 |
47 | cmd = 'from setuptools.command.easy_install import main; main()'
48 | ws = pkg_resources.working_set
49 | assert os.spawnle(
50 | os.P_WAIT, sys.executable, quote (sys.executable),
51 | '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout',
52 | dict(os.environ,
53 | PYTHONPATH=
54 | ws.find(pkg_resources.Requirement.parse('setuptools')).location
55 | ),
56 | ) == 0
57 |
58 | ws.add_entry(tmpeggs)
59 | ws.require('zc.buildout')
60 | import zc.buildout.buildout
61 | zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
62 | shutil.rmtree(tmpeggs)
63 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/.svn/text-base/tests.py.svn-base:
--------------------------------------------------------------------------------
1 | """
2 | >>> from django.test import Client
3 | >>> from basic.blog.models import Post, Category
4 | >>> import datetime
5 | >>> from django.core.urlresolvers import reverse
6 | >>> client = Client()
7 |
8 | >>> category = Category(title='Django', slug='django')
9 | >>> category.save()
10 | >>> category2 = Category(title='Rails', slug='rails')
11 | >>> category2.save()
12 |
13 | >>> post = Post(title='DJ Ango', slug='dj-ango', body='Yo DJ! Turn that music up!', status=2, publish=datetime.datetime(2008,5,5,16,20))
14 | >>> post.save()
15 |
16 | >>> post2 = Post(title='Where my grails at?', slug='where', body='I Can haz Holy plez?', status=2, publish=datetime.datetime(2008,4,2,11,11))
17 | >>> post2.save()
18 |
19 | >>> post.categories.add(category)
20 | >>> post2.categories.add(category2)
21 |
22 | >>> response = client.get(reverse('blog_index'))
23 | >>> response.context[-1]['object_list']
24 | [, ]
25 | >>> response.status_code
26 | 200
27 |
28 | >>> response = client.get(reverse('blog_category_list'))
29 | >>> response.context[-1]['object_list']
30 | [, ]
31 | >>> response.status_code
32 | 200
33 |
34 | >>> response = client.get(category.get_absolute_url())
35 | >>> response.context[-1]['object_list']
36 | []
37 | >>> response.status_code
38 | 200
39 |
40 | >>> response = client.get(post.get_absolute_url())
41 | >>> response.context[-1]['object']
42 |
43 | >>> response.status_code
44 | 200
45 |
46 | >>> response = client.get(reverse('blog_search'), {'q': 'DJ'})
47 | >>> response.context[-1]['object_list']
48 | []
49 | >>> response.status_code
50 | 200
51 | >>> response = client.get(reverse('blog_search'), {'q': 'Holy'})
52 | >>> response.context[-1]['object_list']
53 | []
54 | >>> response.status_code
55 | 200
56 | >>> response = client.get(reverse('blog_search'), {'q': ''})
57 | >>> response.context[-1]['message']
58 | 'Search term was too vague. Please try again.'
59 |
60 | >>> response = client.get(reverse('blog_detail', args=[2008, 'apr', 2, 'where']))
61 | >>> response.context[-1]['object']
62 |
63 | >>> response.status_code
64 | 200
65 | """
66 |
67 |
--------------------------------------------------------------------------------
/fixture/setup_cmd/userdocs.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from distutils.cmd import Command
4 | import os, sys, shutil
5 | from os import path
6 | import optparse
7 | from fixture import docs
8 | from fixture.test import teardown_examples
9 | from docutils.core import (
10 | publish_file, publish_string, publish_doctree, publish_from_doctree)
11 |
12 | class userdocs(Command):
13 | description = "create user documentation"
14 | user_options = [
15 | # ('optname=', None, ""),
16 | ]
17 | # boolean_options = ['update']
18 |
19 | def initialize_options(self):
20 | pass
21 |
22 | def finalize_options(self):
23 | pass
24 |
25 | def run(self):
26 | """build end-user documentation."""
27 |
28 | # if options.build_dir:
29 | # docs.builddir = options.build_dir
30 | if not path.exists(docs.builddir):
31 | os.mkdir(docs.builddir)
32 | docs.state_is_api = False
33 | docsdir = path.join(docs.builddir, 'docs')
34 | if not path.exists(docsdir):
35 | os.mkdir(docsdir)
36 |
37 | teardown_examples() # clear tmp files
38 | stylesheet = path.join(docs.srcdir, 'farmdev-docutils.css')
39 | body = publish_file(open(path.join(docs.srcdir, 'index.rst'), 'r'),
40 | destination=open(path.join(docsdir, 'index.html'), 'w'),
41 | writer_name='html',
42 | settings_overrides={'stylesheet_path': stylesheet},
43 | # settings_overrides={'halt_level':2,
44 | # 'report_level':5}
45 | )
46 | f = open(path.join(docsdir, 'index.html'), 'w')
47 | f.write(body)
48 | f.close()
49 | shutil.copy(path.join(docs.srcdir, 'html4css1.css'),
50 | path.join(docsdir, 'html4css1.css'))
51 | shutil.copy(stylesheet,
52 | path.join(docsdir, 'farmdev-docutils.css'))
53 | images_target = path.join(docsdir, 'images')
54 | if path.exists(images_target):
55 | shutil.rmtree(images_target)
56 | shutil.copytree(path.join(docs.srcdir, 'images'), images_target)
57 | print "built user docs to %s" % docsdir
58 |
59 |
--------------------------------------------------------------------------------
/fixture/django_testcase.py:
--------------------------------------------------------------------------------
1 | import django
2 | from django.conf import settings
3 | from django.db import transaction
4 | from django.db.models import connection
5 | from django.test import testcases
6 | from fixture import DjangoFixture
7 |
8 |
9 | if django.VERSION[:2] < (1, 3):
10 | check_supports_transactions = lambda conn: conn.creation._rollback_works()
11 | else:
12 | def check_supports_transactions(conn):
13 | conn.features.confirm()
14 | return conn.features.supports_transactions
15 |
16 |
17 | class FixtureTestCase(testcases.TransactionTestCase):
18 | """Overrides django's fixture setup and teardown code to use DataSets.
19 |
20 | Starts a transaction at the begining of a test and rolls it back at the
21 | end.
22 |
23 | See :ref:`Using Fixture With Django ` for a complete example.
24 | """
25 |
26 | def _fixture_setup(self):
27 | """Finds a list called :attr:`datasets` and loads them
28 |
29 | This is done in a transaction if possible.
30 | I'm not using the settings.DATABASE_SUPPORTS_TRANSACTIONS as I don't
31 | wnat to assume that :meth:`connection.create_test_db` might not have been
32 | called
33 | """
34 | if check_supports_transactions(connection):
35 | transaction.enter_transaction_management()
36 | transaction.managed(True)
37 | testcases.disable_transaction_methods()
38 |
39 | from django.contrib.sites.models import Site
40 | Site.objects.clear_cache()
41 |
42 | if not hasattr(self, 'fixture'):
43 | self.fixture = DjangoFixture()
44 | if hasattr(self, 'datasets'):
45 | self.data = self.fixture.data(*self.datasets)
46 | self.data.setup()
47 |
48 | def _fixture_teardown(self):
49 | """Finds an attribute called :attr:`data` and runs teardown on it
50 |
51 | (data is created by :meth:`_fixture_setup`)
52 | """
53 | if hasattr(self, 'data'):
54 | self.data.teardown()
55 |
56 | if check_supports_transactions(connection):
57 | testcases.restore_transaction_methods()
58 | transaction.rollback()
59 | transaction.leave_transaction_management()
60 | connection.close()
61 |
--------------------------------------------------------------------------------
/fixture/examples/pylons_example/addressbook/addressbook/tests/__init__.py:
--------------------------------------------------------------------------------
1 | """Pylons application test package
2 |
3 | This package assumes the Pylons environment is already loaded, such as
4 | when this script is imported from the `nosetests --with-pylons=test.ini`
5 | command.
6 |
7 | This module initializes the application via ``websetup`` (`paster
8 | setup-app`) and provides the base testing objects.
9 | """
10 | from unittest import TestCase
11 |
12 | from paste.deploy import loadapp
13 | from paste.script.appinstall import SetupCommand
14 | from pylons import config, url
15 | from routes.util import URLGenerator
16 | from webtest import TestApp
17 |
18 | # additional imports ...
19 | from paste.deploy import appconfig
20 | from addressbook.config.environment import load_environment
21 |
22 | import pylons.test
23 |
24 | # export dbfixture here for tests :
25 | __all__ = ['environ', 'url', 'TestController', 'dbfixture']
26 |
27 | # Invoke websetup with the current config file
28 | ##### comment this out so that initial data isn't loaded:
29 | # SetupCommand('setup-app').run([config['__file__']])
30 |
31 | ##### but add this so that your models get configured:
32 | appconf = appconfig('config:' + config['__file__'])
33 | load_environment(appconf.global_conf, appconf.local_conf)
34 |
35 | environ = {}
36 |
37 | from addressbook import model
38 | from addressbook.model import meta
39 | from fixture import SQLAlchemyFixture
40 | from fixture.style import NamedDataStyle
41 |
42 | dbfixture = SQLAlchemyFixture(
43 | env=model,
44 | engine=meta.engine,
45 | style=NamedDataStyle()
46 | )
47 |
48 | def setup():
49 | meta.metadata.create_all(meta.engine)
50 |
51 | def teardown():
52 | meta.metadata.drop_all(meta.engine)
53 |
54 | class TestController(TestCase):
55 |
56 | def __init__(self, *args, **kwargs):
57 | if pylons.test.pylonsapp:
58 | wsgiapp = pylons.test.pylonsapp
59 | else:
60 | wsgiapp = loadapp('config:%s' % config['__file__'])
61 | self.app = TestApp(wsgiapp)
62 | url._push_object(URLGenerator(config['routes.map'], environ))
63 | TestCase.__init__(self, *args, **kwargs)
64 |
65 | def setUp(self):
66 | # remove the session once per test so that
67 | # objects do not leak from test to test
68 | meta.Session.remove()
69 |
--------------------------------------------------------------------------------
/fixture/examples/pylons_example/addressbook/development.ini:
--------------------------------------------------------------------------------
1 | #
2 | # addressbook - Pylons development environment configuration
3 | #
4 | # The %(here)s variable will be replaced with the parent directory of this file
5 | #
6 | [DEFAULT]
7 | debug = true
8 | # Uncomment and replace with the address which should receive any error reports
9 | #email_to = you@yourdomain.com
10 | smtp_server = localhost
11 | error_email_from = paste@localhost
12 |
13 | [server:main]
14 | use = egg:Paste#http
15 | host = 127.0.0.1
16 | port = 5000
17 |
18 | [app:main]
19 | use = egg:addressbook
20 | full_stack = true
21 | static_files = true
22 |
23 | cache_dir = %(here)s/data
24 | beaker.session.key = addressbook
25 | beaker.session.secret = somesecret
26 |
27 | # If you'd like to fine-tune the individual locations of the cache data dirs
28 | # for the Cache data, or the Session saves, un-comment the desired settings
29 | # here:
30 | #beaker.cache.data_dir = %(here)s/data/cache
31 | #beaker.session.data_dir = %(here)s/data/sessions
32 |
33 | # SQLAlchemy database URL
34 | sqlalchemy.url = sqlite:///%(here)s/development.db
35 |
36 | # WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*
37 | # Debug mode will enable the interactive debugging tool, allowing ANYONE to
38 | # execute malicious code after an exception is raised.
39 | #set debug = false
40 |
41 |
42 | # Logging configuration
43 | [loggers]
44 | keys = root, routes, addressbook, sqlalchemy
45 |
46 | [handlers]
47 | keys = console
48 |
49 | [formatters]
50 | keys = generic
51 |
52 | [logger_root]
53 | level = INFO
54 | handlers = console
55 |
56 | [logger_routes]
57 | level = INFO
58 | handlers =
59 | qualname = routes.middleware
60 | # "level = DEBUG" logs the route matched and routing variables.
61 |
62 | [logger_addressbook]
63 | level = DEBUG
64 | handlers =
65 | qualname = addressbook
66 |
67 | [logger_sqlalchemy]
68 | level = INFO
69 | handlers =
70 | qualname = sqlalchemy.engine
71 | # "level = INFO" logs SQL queries.
72 | # "level = DEBUG" logs SQL queries and results.
73 | # "level = WARN" logs neither. (Recommended for production systems.)
74 |
75 | [handler_console]
76 | class = StreamHandler
77 | args = (sys.stderr,)
78 | level = NOTSET
79 | formatter = generic
80 |
81 | [formatter_generic]
82 | format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
83 | datefmt = %H:%M:%S
84 |
--------------------------------------------------------------------------------
/fixture/examples/google_appengine_example/load_data_locally.py:
--------------------------------------------------------------------------------
1 |
2 | import sys
3 | import os
4 | import optparse
5 | from fixture import GoogleDatastoreFixture
6 | from fixture.style import NamedDataStyle
7 |
8 | def main():
9 | p = optparse.OptionParser(usage="%prog [options]")
10 | default = "/tmp/dev_appserver.datastore"
11 | p.add_option("--datastore_path", default=default, help=(
12 | "Path to datastore file. This must match the value used for "
13 | "the same option when running dev_appserver.py if you want to view the data. "
14 | "Default: %s" % default))
15 | default = "/tmp/dev_appserver.datastore.history"
16 | p.add_option("--history_path", default=default, help=(
17 | "Path to datastore history file. This doesn't need to match the one you use for "
18 | "dev_appserver.py. Default: %s" % default))
19 | default = "/usr/local/google_appengine"
20 | p.add_option("--google_path", default=default, help=(
21 | "Path to google module directory. Default: %s" % default))
22 | (options, args) = p.parse_args()
23 |
24 | if not os.path.exists(options.google_path):
25 | p.error("Could not find google module path at %s. You'll need to specify the path" % options.google_path)
26 |
27 | groot = options.google_path
28 | sys.path.append(groot)
29 | sys.path.append(os.path.join(groot, "lib/django"))
30 | sys.path.append(os.path.join(groot, "lib/webob"))
31 | sys.path.append(os.path.join(groot, "lib/yaml/lib"))
32 |
33 | from google.appengine.tools import dev_appserver
34 | from gblog import models
35 | from tests import datasets
36 |
37 | config, explicit_matcher = dev_appserver.LoadAppConfig(os.path.dirname(__file__), {})
38 | dev_appserver.SetupStubs(
39 | config.application,
40 | clear_datastore = False, # just removes the files when True
41 | datastore_path = options.datastore_path,
42 | history_path = options.history_path,
43 | login_url = None)
44 |
45 | datafixture = GoogleDatastoreFixture(env=models, style=NamedDataStyle())
46 |
47 | data = datafixture.data(datasets.CommentData, datasets.EntryData)
48 | data.setup()
49 | print "Data loaded into datastore %s" % (options.datastore_path or "[default]")
50 |
51 | if __name__ == '__main__':
52 | main()
--------------------------------------------------------------------------------
/fixture/examples/db/storm_examples.py:
--------------------------------------------------------------------------------
1 |
2 | """examples for using Storm fixtures."""
3 |
4 | try:
5 | import storm
6 | except ImportError:
7 | storm = None
8 |
9 | Category, Product, Offer = None, None, None
10 |
11 | if storm:
12 | from storm.locals import *
13 |
14 | class Category(Storm):
15 | __storm_table__ = 'fixture_storm_category'
16 | id = Int(primary=True)
17 | name = RawStr()
18 |
19 | class Product(Storm):
20 | __storm_table__ = 'fixture_storm_product'
21 | id = Int(primary=True)
22 | name = RawStr()
23 | category_id = Int()
24 | category = Reference(category_id, Category.id)
25 |
26 | class Offer(Storm):
27 | __storm_table__ = 'fixture_storm_offer'
28 | id = Int(primary=True)
29 | name = RawStr()
30 | category_id = Int()
31 | category = Reference(category_id, Category.id)
32 | product_id = Int()
33 | product = Reference(product_id, Product.id)
34 |
35 | def setup_db(conn):
36 | assert conn is not None
37 | conn.rollback()
38 | backend = conn._connection.__class__.__name__
39 | tmpl = {
40 | 'pk': {'PostgresConnection' : 'serial primary key',
41 | }.get(backend, 'integer primary key'),
42 | 'str_type': {'PostgresConnection' : 'bytea',
43 | }.get(backend, 'text collate binary')
44 | }
45 | # NOTE: this SQL works in postgres and sqlite:
46 | conn.execute(SQL("""DROP TABLE IF EXISTS fixture_storm_category"""))
47 | conn.execute(SQL("""CREATE TABLE fixture_storm_category (
48 | id %(pk)s,
49 | name %(str_type)s
50 | )""" % tmpl))
51 | assert conn.find(Category).count() == 0
52 | conn.execute(SQL("""CREATE TABLE fixture_storm_product (
53 | id %(pk)s,
54 | name %(str_type)s,
55 | category_id integer
56 | )""" % tmpl))
57 | assert conn.find(Product).count() == 0
58 | conn.execute(SQL("""DROP TABLE IF EXISTS fixture_storm_offer"""))
59 | conn.execute(SQL("""CREATE TABLE fixture_storm_offer (
60 | id %(pk)s,
61 | name %(str_type)s,
62 | category_id integer,
63 | product_id integer
64 | )""" % tmpl))
65 | assert conn.find(Offer).count() == 0
66 | conn.commit()
67 |
68 | def teardown_db(conn):
69 | assert conn is not None
70 |
71 | conn.rollback()
72 | for tb in (Offer, Product, Category):
73 | conn.execute(SQL('drop table '+tb.__storm_table__))
74 | conn.commit()
75 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templates/blog/post_detail.html:
--------------------------------------------------------------------------------
1 | {% extends "blog/base_blog.html" %}
2 |
3 |
4 | {% block title %}{{ object.title }}{% endblock %}
5 | {% block body_class %}{{ block.super }} post_detail{% endblock %}
6 | {% block body_id %}post_{{ object.id }}{% endblock %}
7 |
8 |
9 | {% block content_title %}
10 | {{ object.title }}
11 |
12 | {% if object.get_previous_by_publish %}
13 | « {{ object.get_previous_post }}
14 | {% endif %}
15 | {% if object.get_next_by_publish %}
16 | | {{ object.get_next_post }} »
17 | {% endif %}
18 |
19 | {% endblock %}
20 |
21 |
22 | {% block content %}
23 | {% load blog markup comments tagging_tags %}
24 |
25 | {{ object.publish|date:"j F Y" }}
26 |
27 |
28 | {{ object.body|markdown:"safe" }}
29 |
30 |
31 | {% tags_for_object object as tag_list %}
32 | {% if tag_list %}
33 | Related tags:
34 | {% for tag in tag_list %}
35 | {{ tag }}{% if not forloop.last %}, {% endif %}
36 | {% endfor %}
37 |
38 | {% endif %}
39 |
40 | {% get_comment_list for object as comment_list %}
41 | {% if comment_list %}
42 |
58 | {% endif %}
59 | {% if object.allow_comments %}
60 | {% render_comment_form for object %}
61 | {% else %}
62 |
66 | {% endif %}
67 | {% endblock %}
--------------------------------------------------------------------------------
/fixture/test/test_loadable/test_django/test_djangoenv.py:
--------------------------------------------------------------------------------
1 | from nose.tools import raises, assert_raises, assert_equal
2 | from fixture.loadable.django_loadable import DjangoEnv, DjangoFixture
3 | from fixture.examples.django_example.blog.models import Post
4 | from fixture import DataSet
5 | from fixture.style import NamedDataStyle
6 |
7 | @raises(ValueError)
8 | def test_unsplittable_name():
9 | DjangoEnv.get('blog_Post')
10 |
11 | def test_invalid_app_returns_none():
12 | assert_equal(None, DjangoEnv.get('no_such_app__Post'))
13 |
14 | def test_invalid_model_returns_none():
15 | assert_equal(None, DjangoEnv.get('blog__NoSuchModel'))
16 |
17 | def test_model_lookup_by_qualified_model_name():
18 |
19 | class SomeDataset(DataSet):
20 | class Meta:
21 | django_model = "blog.Post"
22 | class foo:
23 | foo = 1
24 |
25 | fixture = DjangoFixture()
26 | ds = SomeDataset()
27 | fixture.attach_storage_medium(ds)
28 | assert_equal(ds.meta.storage_medium.medium, Post)
29 |
30 | def test_model_lookup_by_explicit_app_label_and_name():
31 |
32 | class SomeDataset(DataSet):
33 | class Meta:
34 | django_app_label = "blog"
35 | storable_name = "Post"
36 | class foo:
37 | foo = 1
38 |
39 | fixture = DjangoFixture()
40 | ds = SomeDataset()
41 | fixture.attach_storage_medium(ds)
42 | assert_equal(ds.meta.storage_medium.medium, Post)
43 |
44 | def test_model_lookup_by_app_label_and_style_derived_name():
45 |
46 | class PostData(DataSet):
47 | class Meta:
48 | django_app_label = "blog"
49 | class foo:
50 | foo = 1
51 |
52 | fixture = DjangoFixture(style=NamedDataStyle())
53 | ds = PostData()
54 | fixture.attach_storage_medium(ds)
55 | assert_equal(ds.meta.storage_medium.medium, Post)
56 |
57 | @raises(ValueError)
58 | def test_dataset_with_malformed_model_name():
59 |
60 | class SomeDataset(DataSet):
61 | class Meta:
62 | django_model = "not_dot_separated_model_name"
63 | class foo:
64 | foo = 1
65 |
66 | fixture = DjangoFixture()
67 | ds = SomeDataset()
68 | fixture.attach_storage_medium(ds)
69 |
70 | @raises(ValueError)
71 | def test_dataset_without_resolvable_model_name():
72 |
73 | class UnknownData(DataSet):
74 | class foo:
75 | foo = 1
76 |
77 | fixture = DjangoFixture()
78 | ds = UnknownData()
79 | fixture.attach_storage_medium(ds)
80 |
81 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templates/blog/.svn/text-base/post_detail.html.svn-base:
--------------------------------------------------------------------------------
1 | {% extends "blog/base_blog.html" %}
2 |
3 |
4 | {% block title %}{{ object.title }}{% endblock %}
5 | {% block body_class %}{{ block.super }} post_detail{% endblock %}
6 | {% block body_id %}post_{{ object.id }}{% endblock %}
7 |
8 |
9 | {% block content_title %}
10 | {{ object.title }}
11 |
12 | {% if object.get_previous_by_publish %}
13 | « {{ object.get_previous_post }}
14 | {% endif %}
15 | {% if object.get_next_by_publish %}
16 | | {{ object.get_next_post }} »
17 | {% endif %}
18 |
19 | {% endblock %}
20 |
21 |
22 | {% block content %}
23 | {% load blog markup comments tagging_tags %}
24 |
25 | {{ object.publish|date:"j F Y" }}
26 |
27 |
28 | {{ object.body|markdown:"safe" }}
29 |
30 |
31 | {% tags_for_object object as tag_list %}
32 | {% if tag_list %}
33 | Related tags:
34 | {% for tag in tag_list %}
35 | {{ tag }}{% if not forloop.last %}, {% endif %}
36 | {% endfor %}
37 |
38 | {% endif %}
39 |
40 | {% get_comment_list for object as comment_list %}
41 | {% if comment_list %}
42 |
58 | {% endif %}
59 | {% if object.allow_comments %}
60 | {% render_comment_form for object %}
61 | {% else %}
62 |
66 | {% endif %}
67 | {% endblock %}
--------------------------------------------------------------------------------
/fixture/examples/db/sqlalchemy_examples.py:
--------------------------------------------------------------------------------
1 |
2 | """Examples for using sqlalchemy fixtures.
3 |
4 | See a complete, more accurate example in http://farmdev.com/projects/fixture/docs/
5 |
6 | """
7 |
8 | try:
9 | import sqlalchemy
10 | except ImportError:
11 | sqlalchemy = None
12 |
13 | Category, Product, Offer = None, None, None
14 |
15 | if sqlalchemy:
16 | from sqlalchemy import *
17 | from sqlalchemy.orm import *
18 | metadata = MetaData()
19 |
20 | categories = Table("fixture_sqlalchemy_category",
21 | metadata,
22 | Column("id", INT, primary_key=True),
23 | Column("name", String(100) )
24 | )
25 | class Category(object):
26 | pass
27 |
28 | products = Table("fixture_sqlalchemy_product",
29 | metadata,
30 | Column("id", INT, primary_key=True),
31 | Column("name", String(100) ),
32 | Column("category_id", INT,
33 | ForeignKey("fixture_sqlalchemy_category.id")),
34 | )
35 | class Product(object):
36 | pass
37 |
38 | offers = Table("fixture_sqlalchemy_offer",
39 | metadata,
40 | Column("id", INT, primary_key=True),
41 | Column("name", String(100) ),
42 | Column("category_id", INT,
43 | ForeignKey("fixture_sqlalchemy_category.id")),
44 | Column("product_id", INT,
45 | ForeignKey("fixture_sqlalchemy_product.id")),
46 | )
47 | class Offer(object):
48 | pass
49 |
50 | authors = Table('authors', metadata,
51 | Column('id', Integer, primary_key=True),
52 | Column('first_name', String(100)),
53 | Column('last_name', String(100)))
54 |
55 | class Author(object):
56 | pass
57 |
58 | books = Table('books', metadata,
59 | Column('id', Integer, primary_key=True),
60 | Column('title', String(100)),
61 | Column('author_id', Integer, ForeignKey('authors.id')))
62 |
63 | class Book(object):
64 | pass
65 |
66 | def connect(dsn):
67 | metadata.bind = create_engine(dsn)
68 |
69 | def setup_mappers():
70 | mapper(Category, categories)
71 | mapper(Product, products, properties={
72 | 'category': relation(Category),
73 | })
74 | mapper(Offer, offers, properties={
75 | 'category': relation(Category, backref='products'),
76 | 'product': relation(Product)
77 | })
78 | mapper(Author, authors)
79 | mapper(Book, books, properties={
80 | 'author': relation(Author)
81 | })
82 |
83 | if __name__ == '__main__':
84 | import doctest
85 | doctest.testmod()
--------------------------------------------------------------------------------
/fixture/loadable/storm_loadable.py:
--------------------------------------------------------------------------------
1 |
2 | """Components for loading and unloading data using `Storm`_.
3 |
4 | See :ref:`Using LoadableFixture` for examples.
5 |
6 | .. _Storm: https://storm.canonical.com/
7 |
8 | """
9 |
10 | from fixture.loadable import DBLoadableFixture
11 | from fixture.util import _mklog
12 |
13 | stlog = _mklog('fixture.loadable.storm')
14 |
15 | class StormMedium(DBLoadableFixture.StorageMediumAdapter):
16 |
17 | def clear(self, obj):
18 | self.transaction.remove(obj)
19 |
20 | def save(self, row, column_vals):
21 | from storm.info import get_cls_info
22 | from storm.locals import ReferenceSet, Store
23 |
24 | cls_info = get_cls_info(self.medium)
25 |
26 | column_vals = list(column_vals)
27 | pk = []
28 | for n, v in column_vals:
29 | propid = id(getattr(self.medium, n))
30 | if propid in cls_info.primary_key_idx:
31 | pk.append((cls_info.primary_key_idx[propid], v, n))
32 |
33 | assert len(pk) == 0 or len(pk) == len(cls_info.primary_key), (
34 | "Incomplete primary key see %s need %s" % (
35 | [x[2] for x in pk], [x.name for x in cls_info.primary_key]))
36 |
37 | if pk:
38 | obj = self.transaction.get(self.medium, tuple([x[1] for x in sorted(pk)]))
39 | else:
40 | obj = None
41 |
42 | if obj is None:
43 | obj = self.medium()
44 | self.transaction.add(obj)
45 |
46 | assert Store.of(obj) is self.transaction
47 |
48 | for n, v in column_vals:
49 | if isinstance(getattr(self.medium,n), ReferenceSet):
50 | getattr(obj, n).add(v)
51 | else:
52 | setattr(obj, n, v)
53 |
54 | self.transaction.flush()
55 | stlog.info("%s %s", obj, [(n,getattr(obj,n)) for n in row.columns()])
56 |
57 | return obj
58 |
59 | def visit_loader(self, loader):
60 | """Visit the loader and store a reference to the transaction connection"""
61 | self.transaction = loader.transaction
62 |
63 |
64 | pass
65 |
66 | class StormFixture(DBLoadableFixture):
67 | StormMedium = StormMedium
68 | Medium = StormMedium
69 |
70 | def __init__(self, store=None, use_transaction=True,
71 | close_store=False, **kw ):
72 | DBLoadableFixture.__init__(self, **kw)
73 | self.store = store
74 | self.close_store = close_store
75 | self.use_transaction = use_transaction
76 |
77 | def create_transaction(self):
78 | return self.store
79 |
80 |
81 |
82 | pass
83 |
--------------------------------------------------------------------------------
/fixture/examples/pylons_example/addressbook/addressbook/config/middleware.py:
--------------------------------------------------------------------------------
1 | """Pylons middleware initialization"""
2 | from beaker.middleware import CacheMiddleware, SessionMiddleware
3 | from paste.cascade import Cascade
4 | from paste.registry import RegistryManager
5 | from paste.urlparser import StaticURLParser
6 | from paste.deploy.converters import asbool
7 | from pylons import config
8 | from pylons.middleware import ErrorHandler, StatusCodeRedirect
9 | from pylons.wsgiapp import PylonsApp
10 | from routes.middleware import RoutesMiddleware
11 |
12 | from addressbook.config.environment import load_environment
13 |
14 | def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
15 | """Create a Pylons WSGI application and return it
16 |
17 | ``global_conf``
18 | The inherited configuration for this application. Normally from
19 | the [DEFAULT] section of the Paste ini file.
20 |
21 | ``full_stack``
22 | Whether this application provides a full WSGI stack (by default,
23 | meaning it handles its own exceptions and errors). Disable
24 | full_stack when this application is "managed" by another WSGI
25 | middleware.
26 |
27 | ``static_files``
28 | Whether this application serves its own static files; disable
29 | when another web server is responsible for serving them.
30 |
31 | ``app_conf``
32 | The application's local configuration. Normally specified in
33 | the [app:] section of the Paste ini file (where
34 | defaults to main).
35 |
36 | """
37 | # Configure the Pylons environment
38 | load_environment(global_conf, app_conf)
39 |
40 | # The Pylons WSGI app
41 | app = PylonsApp()
42 |
43 | # Routing/Session/Cache Middleware
44 | app = RoutesMiddleware(app, config['routes.map'])
45 | app = SessionMiddleware(app, config)
46 | app = CacheMiddleware(app, config)
47 |
48 | # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
49 |
50 | if asbool(full_stack):
51 | # Handle Python exceptions
52 | app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
53 |
54 | # Display error documents for 401, 403, 404 status codes (and
55 | # 500 when debug is disabled)
56 | if asbool(config['debug']):
57 | app = StatusCodeRedirect(app)
58 | else:
59 | app = StatusCodeRedirect(app, [400, 401, 403, 404, 500])
60 |
61 | # Establish the Registry for this application
62 | app = RegistryManager(app)
63 |
64 | if asbool(static_files):
65 | # Serve static files
66 | static_app = StaticURLParser(config['pylons.paths']['static_files'])
67 | app = Cascade([static_app, app])
68 |
69 | return app
70 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = PATH=../bin sphinx-build
7 | PAPER =
8 |
9 | # Internal variables.
10 | PAPEROPT_a4 = -D latex_paper_size=a4
11 | PAPEROPT_letter = -D latex_paper_size=letter
12 | ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
13 |
14 | .PHONY: help clean html web pickle htmlhelp latex changes linkcheck
15 |
16 | test:
17 | cd ..; nosetests
18 |
19 | docs_live:
20 | tar -czf ./build/fixture-docs.tgz build/html
21 | scp ./build/fixture-docs.tgz fisk.rcache.com:~/www/farmdev/projects/fixture/
22 | @echo "uploaded docs"
23 |
24 | help:
25 | @echo "Please use \`make ' where is one of"
26 | @echo " html to make standalone HTML files"
27 | @echo " pickle to make pickle files (usable by e.g. sphinx-web)"
28 | @echo " htmlhelp to make HTML files and a HTML help project"
29 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
30 | @echo " changes to make an overview over all changed/added/deprecated items"
31 | @echo " linkcheck to check all external links for integrity"
32 |
33 | clean:
34 | -rm -rf build/*
35 |
36 | html:
37 | mkdir -p build/html build/doctrees
38 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html
39 | @echo
40 | @echo "Build finished. The HTML pages are in build/html."
41 |
42 | doctest:
43 | mkdir -p build/html build/doctrees
44 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) build/html
45 | @echo
46 | @echo "Doctest finished."
47 |
48 | pickle:
49 | mkdir -p build/pickle build/doctrees
50 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle
51 | @echo
52 | @echo "Build finished; now you can process the pickle files or run"
53 | @echo " sphinx-web build/pickle"
54 | @echo "to start the sphinx-web server."
55 |
56 | web: pickle
57 |
58 | htmlhelp:
59 | mkdir -p build/htmlhelp build/doctrees
60 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp
61 | @echo
62 | @echo "Build finished; now you can run HTML Help Workshop with the" \
63 | ".hhp project file in build/htmlhelp."
64 |
65 | latex:
66 | mkdir -p build/latex build/doctrees
67 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex
68 | @echo
69 | @echo "Build finished; the LaTeX files are in build/latex."
70 | @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
71 | "run these through (pdf)latex."
72 |
73 | changes:
74 | mkdir -p build/changes build/doctrees
75 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes
76 | @echo
77 | @echo "The overview file is in build/changes."
78 |
79 | linkcheck:
80 | mkdir -p build/linkcheck build/doctrees
81 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck
82 | @echo
83 | @echo "Link check complete; look for any errors in the above output " \
84 | "or in build/linkcheck/output.txt."
85 |
--------------------------------------------------------------------------------
/fixture/test/test_command/test_generate/test_generate.py:
--------------------------------------------------------------------------------
1 |
2 | import sys
3 | from nose.tools import eq_, raises, with_setup
4 | from fixture.test import attr
5 | from fixture.command.generate import *
6 |
7 | class Stranger(object):
8 | """something that cannot produce data."""
9 | pass
10 |
11 | @raises(UnrecognizedObject)
12 | @attr(unit=True)
13 | def test_unhandlable_object():
14 | generate = DataSetGenerator({})
15 | generate(".".join([Stranger.__module__, Stranger.__name__]))
16 |
17 | class MyHandler(DataHandler):
18 | @staticmethod
19 | def recognizes(obj_path, obj=None):
20 | if obj_path == "myhandler.object_path":
21 | return True
22 |
23 | def register_myhandler():
24 | register_handler(MyHandler)
25 |
26 | _saved_registry = [h for h in handler_registry]
27 | def reset_handlers():
28 | handler_registry[:] = [h for h in _saved_registry]
29 |
30 | @attr(unit=True)
31 | @with_setup(setup=register_myhandler, teardown=reset_handlers)
32 | def test_dataset_handler():
33 | g = DataSetGenerator({})
34 | hnd = g.get_handler("myhandler.object_path")
35 | assert isinstance(hnd, MyHandler)
36 |
37 |
38 | @attr(unit=True)
39 | @raises(UnrecognizedObject)
40 | @with_setup(setup=register_myhandler, teardown=reset_handlers)
41 | def test_unrecognized_dataset_handler():
42 | g = DataSetGenerator({})
43 | hnd = g.get_handler("NOTHONG")
44 |
45 | @attr(unit=True)
46 | def test_requires_option():
47 | required_idents = []
48 | def mock_require(ident):
49 | required_idents.append(ident)
50 | import pkg_resources
51 | orig_require = pkg_resources.require
52 | pkg_resources.require = mock_require
53 | sys.stderr = sys.stdout
54 | try:
55 | try:
56 | dataset_generator([ 'bad.object.path',
57 | '--require-egg=foo==1.0', '--require-egg=baz>=2.0b'])
58 | except SystemExit, e:
59 | pass
60 | finally:
61 | pkg_resources.require = orig_require
62 | sys.stderr = sys.__stderr__
63 | eq_(required_idents, ['foo==1.0', 'baz>=2.0b'])
64 |
65 | def some_function():
66 | pass
67 |
68 | class SomeClass(object):
69 | def some_method(self):
70 | pass
71 |
72 | @attr(unit=1)
73 | def test_resolve_path_to_function():
74 | eq_(resolve_function_path("%s:some_function" % __name__), some_function)
75 |
76 | @attr(unit=1)
77 | def test_resolve_path_to_method():
78 | eq_(resolve_function_path("%s:SomeClass.some_method" % __name__), SomeClass.some_method)
79 |
80 | @attr(unit=1)
81 | def test_resolve_path_to_module():
82 | # Note that this is not realistic. I think we'd always want a callable
83 | eq_(resolve_function_path("%s" % __name__), sys.modules[__name__])
84 |
85 | @attr(unit=1)
86 | @raises(ImportError)
87 | def test_resolve_bad_path():
88 | resolve_function_path("nomoduleshouldbenamedthis.nowhere:Babu")
89 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/.svn/text-base/models.py.svn-base:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from django.utils.translation import ugettext_lazy as _
3 | from django.db.models import permalink
4 | from django.contrib.auth.models import User
5 | from tagging.fields import TagField
6 | from basic.blog.managers import PublicManager
7 |
8 | import tagging
9 |
10 |
11 | class Category(models.Model):
12 | """Category model."""
13 | title = models.CharField(_('title'), max_length=100)
14 | slug = models.SlugField(_('slug'), unique=True)
15 |
16 | class Meta:
17 | verbose_name = _('category')
18 | verbose_name_plural = _('categories')
19 | db_table = 'blog_categories'
20 | ordering = ('title',)
21 |
22 | class Admin:
23 | pass
24 |
25 | def __unicode__(self):
26 | return u'%s' % self.title
27 |
28 | @permalink
29 | def get_absolute_url(self):
30 | return ('blog_category_detail', None, {'slug': self.slug})
31 |
32 |
33 | class Post(models.Model):
34 | """Post model."""
35 | STATUS_CHOICES = (
36 | (1, _('Draft')),
37 | (2, _('Public')),
38 | )
39 | title = models.CharField(_('title'), max_length=200)
40 | slug = models.SlugField(_('slug'), unique_for_date='publish')
41 | author = models.ForeignKey(User, blank=True, null=True)
42 | body = models.TextField(_('body'))
43 | tease = models.TextField(_('tease'), blank=True)
44 | status = models.IntegerField(_('status'), choices=STATUS_CHOICES, default=2)
45 | allow_comments = models.BooleanField(_('allow comments'), default=True)
46 | publish = models.DateTimeField(_('publish'))
47 | created = models.DateTimeField(_('created'), auto_now_add=True)
48 | modified = models.DateTimeField(_('modified'), auto_now=True)
49 | categories = models.ManyToManyField(Category, blank=True)
50 | tags = TagField()
51 | objects = PublicManager()
52 |
53 | class Meta:
54 | verbose_name = _('post')
55 | verbose_name_plural = _('posts')
56 | db_table = 'blog_posts'
57 | ordering = ('-publish',)
58 | get_latest_by = 'publish'
59 |
60 | class Admin:
61 | list_display = ('title', 'publish', 'status')
62 | list_filter = ('publish', 'categories', 'status')
63 | search_fields = ('title', 'body')
64 |
65 | def __unicode__(self):
66 | return u'%s' % self.title
67 |
68 | @permalink
69 | def get_absolute_url(self):
70 | return ('blog_detail', None, {
71 | 'year': self.publish.year,
72 | 'month': self.publish.strftime('%b').lower(),
73 | 'day': self.publish.day,
74 | 'slug': self.slug
75 | })
76 |
77 | def get_previous_post(self):
78 | return self.get_previous_by_publish(status__gte=2)
79 |
80 | def get_next_post(self):
81 | return self.get_next_by_publish(status__gte=2)
--------------------------------------------------------------------------------
/docs/source/api/fixture.loadable.django_loadable.rst:
--------------------------------------------------------------------------------
1 | ------------------------------------------
2 | fixture.loadable.django_loadable
3 | ------------------------------------------
4 |
5 | .. automodule:: fixture.loadable.django_loadable
6 |
7 |
8 | .. autoclass:: DjangoEnv
9 |
10 | .. automethod:: get
11 |
12 |
13 | .. autoclass:: fixture.loadable.django_loadable.DjangoFixture
14 | :show-inheritance:
15 | :members: create_transaction, then_finally, attach_storage_medium
16 |
17 | Django's transaction management is implemented as a module, which is returned by :meth:`create_transaction`. This means the the :meth:`~fixture.loadable.loadable.DBLoadableFixture.commit` and :meth:`~fixture.loadable.loadable.DBLoadableFixture.rollback` remain unchanged from :class:`fixture.loadable.loadable.DBLoadableFixture`.
18 |
19 | As far as mapping DataSets to models, if you don't supply an env kwarg you'll get the :class:`~DjangoEnv` class. This simply provides a :meth:`get method ` that proxies through to :meth:`django.db.models.get_model`.
20 | Alternatively you can use an inner :class:`Meta ` with the following attribute:
21 |
22 | .. attribute:: django_model
23 |
24 | Use this on an inner :class:`Meta ` class to specify the model.
25 | It must be of a form that can be passed to ``get_model`` after being split on a ``'.'`` e.g:
26 |
27 | .. code-block:: python
28 |
29 | class Meta:
30 | django_model = 'auth.User'
31 |
32 | .. autoclass:: fixture.loadable.django_loadable.DjangoMedium
33 | :show-inheritance:
34 |
35 | For now we're going to say that a Fixture can only define relations
36 | and fields defined locally to the target model. So given the :ref:`example models `, Where Book has a ForeignKey to Author, then you'll have a fixture like:
37 |
38 | .. code-block:: python
39 |
40 | class BookData(DataSet):
41 | class Meta:
42 | django_model = 'app.Book'
43 | class book1:
44 | # ...
45 | author = AuthorData.some_author
46 |
47 | and not like this:
48 |
49 | .. code-block:: python
50 |
51 | class AuthorData(DataSet):
52 | class Meta:
53 | django_model = 'app.Author'
54 | class author1:
55 | # ...
56 | books = [BookData.book1, BookData.book2]
57 |
58 | .. note:: This might change in future as it looks like it should be possible to be able to do it the other way round (if desirable).
59 |
60 | .. automethod:: save
61 |
62 | Validates first with :meth:`_check_schema`
63 |
64 | .. automethod:: _check_schema
65 |
66 | .. note:: see the internal function ``column_vals`` inside :meth:`fixture.loadable.LoadableFixture.load_dataset` for more info
67 |
68 | .. warning:: This will check the field names and related model types only - it won't validate field types
69 |
70 | See the :ref:`example models `
71 |
72 |
--------------------------------------------------------------------------------
/fixture/loadable/google_datastore_loadable.py:
--------------------------------------------------------------------------------
1 | """
2 | Components for loading and unloading data using the Google App Engine `Datastore`_.
3 |
4 | Added in version 1.1
5 |
6 | .. _Datastore: http://code.google.com/appengine/docs/datastore/
7 |
8 | """
9 |
10 | from fixture.loadable import EnvLoadableFixture
11 |
12 | class EntityMedium(EnvLoadableFixture.StorageMediumAdapter):
13 | """
14 | Adapts google.appengine.api.datastore.Entity objects and any
15 | other object that is an instance of Entity
16 | """
17 | def _entities_to_keys(self, mylist):
18 | """Converts an array of datastore objects to an array of keys.
19 |
20 | if the value passed in is not a list, this passes it through as is
21 | """
22 | if type(mylist)==type([]):
23 | if all(map(lambda x: hasattr(x,'key'),mylist)):
24 | return [ent.key() for ent in mylist]
25 | else: # ...no type checks...
26 | return mylist
27 | else:
28 | return mylist
29 |
30 | def clear(self, obj):
31 | """Delete this entity from the Datastore"""
32 | obj.delete()
33 |
34 | def save(self, row, column_vals):
35 | """Save this entity to the Datastore"""
36 | gen=[(k,self._entities_to_keys(v)) for k,v in column_vals]
37 | entity = self.medium(
38 | **dict(gen)
39 | )
40 | entity.put()
41 | return entity
42 |
43 | class GoogleDatastoreFixture(EnvLoadableFixture):
44 | """
45 | A fixture that knows how to load DataSet objects into Google Datastore `Entity`_ objects.
46 |
47 | >>> from fixture import GoogleDatastoreFixture
48 |
49 | See :ref:`Using Fixture With Google App Engine ` for a complete example.
50 |
51 | .. _Entity: http://code.google.com/appengine/docs/datastore/entitiesandmodels.html
52 |
53 | Keyword Arguments:
54 |
55 | ``style``
56 | A :class:`Style ` object to translate names with
57 |
58 | ``env``
59 | A dict or module that contains Entity classes. This will be searched when
60 | :class:`Style ` translates DataSet names into
61 | storage media. See :meth:`EnvLoadableFixture.attach_storage_medium ` for details on
62 | how ``env`` works.
63 |
64 | ``dataclass``
65 | :class:`SuperSet ` class to represent loaded data with
66 |
67 | ``medium``
68 | A custom :class:`StorageMediumAdapter `
69 | class to instantiate when storing a DataSet.
70 | By default, an Entity adapter will be used so you should only set a custom medium
71 | if you know what you doing.
72 |
73 | Added in version 1.1
74 | """
75 | Medium = EntityMedium
76 |
77 | def commit(self):
78 | pass
79 |
80 | def rollback(self):
81 | pass
82 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 |
2 | import sys, os
3 | import ez_setup
4 | ez_setup.use_setuptools()
5 | from setuptools import setup, find_packages
6 | import compiler
7 | import pydoc
8 | from compiler import visitor
9 |
10 | class ModuleVisitor(object):
11 | def __init__(self):
12 | self.mod_doc = None
13 | self.mod_version = None
14 |
15 | def default(self, node):
16 | for child in node.getChildNodes():
17 | self.visit(child)
18 |
19 | def visitModule(self, node):
20 | self.mod_doc = node.doc
21 | self.default(node)
22 |
23 | def visitAssign(self, node):
24 | if self.mod_version:
25 | return
26 | asn = node.nodes[0]
27 | assert asn.name == '__version__', (
28 | "expected __version__ node: %s" % asn)
29 | self.mod_version = node.expr.value
30 | self.default(node)
31 |
32 | def get_module_meta(modfile):
33 | ast = compiler.parseFile(modfile)
34 | modnode = ModuleVisitor()
35 | visitor.walk(ast, modnode)
36 | if modnode.mod_doc is None:
37 | raise RuntimeError(
38 | "could not parse doc string from %s" % modfile)
39 | if modnode.mod_version is None:
40 | raise RuntimeError(
41 | "could not parse __version__ from %s" % modfile)
42 | return (modnode.mod_version,) + pydoc.splitdoc(modnode.mod_doc)
43 |
44 | version, description, long_description = get_module_meta("./fixture/__init__.py")
45 |
46 | setup(
47 | name = 'fixture',
48 | version = version,
49 | author = 'Kumar McMillan',
50 | author_email = 'kumar dot mcmillan / gmail.com',
51 | description = description,
52 | classifiers = [ 'Environment :: Other Environment',
53 | 'Intended Audience :: Developers',
54 | ( 'License :: OSI Approved :: GNU Library or Lesser '
55 | 'General Public License (LGPL)'),
56 | 'Natural Language :: English',
57 | 'Operating System :: OS Independent',
58 | 'Programming Language :: Python',
59 | 'Topic :: Software Development :: Testing',
60 | 'Topic :: Software Development :: Quality Assurance',
61 | 'Topic :: Utilities'],
62 | long_description = long_description,
63 | license = 'GNU Lesser General Public License (LGPL)',
64 | keywords = ('test testing tools unittest fixtures setup teardown '
65 | 'database stubs IO tempfile'),
66 | url = 'http://farmdev.com/projects/fixture/',
67 |
68 | packages = find_packages(),
69 |
70 | test_suite="fixture.setup_test_not_supported",
71 | entry_points = {
72 | 'console_scripts': [ 'fixture = fixture.command.generate:main' ]
73 | },
74 | # the following allows e.g. easy_install fixture[django]
75 | extras_require = {
76 | 'decorators': ['nose>=0.9.2'],
77 | 'sqlalchemy': ['SQLAlchemy>=0.4'],
78 | 'sqlobject': ['SQLObject==0.8'],
79 | 'django': ['django'],
80 | },
81 | )
--------------------------------------------------------------------------------
/fixture/test/test_loadable/test_django/test_djangomeduim.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 | from fixture import DjangoFixture
3 | from fixture.style import NamedDataStyle
4 | from fixture.loadable.django_loadable import field_is_required
5 | from fixtures import *
6 | from util import *
7 | from nose.tools import raises
8 | from fixture.examples.django_example.app import models
9 | from django.db import models as django_models
10 |
11 | def _check_row(medium, column_vals):
12 | medium._check_schema(column_vals)
13 |
14 | def test_schema_conformance():
15 |
16 | valid_rels = ValidNoRelationsData()
17 | invalid_rels = InvalidNoRelationsData()
18 |
19 | class NoRelations(django_models.Model):
20 | char = django_models.CharField(max_length=10)
21 | num = django_models.IntegerField()
22 |
23 | for dataset, model, callable in \
24 | [
25 | (valid_rels, NoRelations, _check_row),
26 | (invalid_rels, NoRelations,
27 | raises(ValueError)(_check_row))
28 | ]:
29 | djm = DjangoFixture.DjangoMedium(NoRelations, dataset)
30 | rows = [(row[0], list(get_column_vals(row[1]))) for row in dataset]
31 | for row in rows:
32 | callable.description = "schema.conformance: %s %s in %s" % (row[0], row[1],
33 | dataset.__class__.__name__)
34 | yield callable, djm, row[1]
35 |
36 | def test_is_field_required():
37 | from django.db import models
38 | class TestMod(models.Model):
39 | pk = models.CharField(primary_key=True)
40 | req = models.CharField()
41 | default_char = models.CharField(default='default_val')
42 | null = models.CharField(null=True)
43 | date = models.DateTimeField(auto_now=True)
44 | req_date = models.DateTimeField()
45 | nullable_date = models.DateTimeField(null=True, auto_now_add=True)
46 | default_date = models.DateTimeField(default=datetime.now)
47 |
48 |
49 | required_matrix = dict(
50 | pk=False,
51 | req=True,
52 | default_char=False,
53 | null=False,
54 | date=False,
55 | req_date=True,
56 | nullable_date=False,
57 | default_date=False,
58 | )
59 |
60 | def check_field_required(fld, result):
61 | msg = "field '%s': null=%s, primary_key=%s, auto_now=%s, auto_now_add=%s " \
62 | "should be %s"
63 | auto_now = getattr(fld, 'auto_now', None)
64 | auto_now_add = getattr(fld, 'auto_now_add', None)
65 | assert field_is_required(fld) == result, msg % (fld.name, fld.null,
66 | fld.primary_key,
67 | auto_now, auto_now_add,
68 | result)
69 |
70 | for item in required_matrix.items():
71 | fld, result = item
72 | check_field_required.description = "%s required? %s" % item
73 | yield check_field_required, TestMod._meta.get_field(fld), result
--------------------------------------------------------------------------------
/fixture/examples/django_example/settings.py:
--------------------------------------------------------------------------------
1 | # Django settings for project project.
2 | import os
3 | DEBUG = True
4 | TEMPLATE_DEBUG = DEBUG
5 |
6 | ADMINS = (
7 | # ('Your Name', 'your_email@domain.com'),
8 | )
9 |
10 | MANAGERS = ADMINS
11 |
12 |
13 | DATABASE_ENGINE = 'sqlite3'
14 | DATABASE_NAME = os.path.join(os.path.dirname(__file__), 'project.db')
15 | # MY POSTGRES SETTINGS
16 | #DATABASE_ENGINE = 'postgresql_psycopg2'
17 | #DATABASE_NAME = 'fixture' #
18 | #DATABASE_USER = 'ben' # Not used with sqlite3.
19 | DATABASE_PASSWORD = '' # Not used with sqlite3.
20 | DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
21 | DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
22 |
23 | # Local time zone for this installation. Choices can be found here:
24 | # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
25 | # although not all choices may be available on all operating systems.
26 | # If running in a Windows environment this must be set to the same as your
27 | # system time zone.
28 | TIME_ZONE = 'America/Chicago'
29 |
30 | # Language code for this installation. All choices can be found here:
31 | # http://www.i18nguy.com/unicode/language-identifiers.html
32 | LANGUAGE_CODE = 'en-us'
33 |
34 | SITE_ID = 1
35 |
36 | # If you set this to False, Django will make some optimizations so as not
37 | # to load the internationalization machinery.
38 | USE_I18N = True
39 |
40 | # Absolute path to the directory that holds media.
41 | # Example: "/home/media/media.lawrence.com/"
42 | MEDIA_ROOT = ''
43 |
44 | # URL that handles the media served from MEDIA_ROOT. Make sure to use a
45 | # trailing slash if there is a path component (optional in other cases).
46 | # Examples: "http://media.lawrence.com", "http://example.com/media/"
47 | MEDIA_URL = ''
48 |
49 | # URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
50 | # trailing slash.
51 | # Examples: "http://foo.com/media/", "/media/".
52 | ADMIN_MEDIA_PREFIX = '/media/'
53 |
54 | # Make this unique, and don't share it with anybody.
55 | SECRET_KEY = 'ng5s##h+-wugvd2xwi2p*#p2g16%11on3=wv33dmx)yp#r*7gw'
56 |
57 | # List of callables that know how to import templates from various sources.
58 | TEMPLATE_LOADERS = (
59 | 'django.template.loaders.filesystem.load_template_source',
60 | 'django.template.loaders.app_directories.load_template_source',
61 | # 'django.template.loaders.eggs.load_template_source',
62 | )
63 |
64 | MIDDLEWARE_CLASSES = (
65 | 'django.middleware.common.CommonMiddleware',
66 | 'django.contrib.sessions.middleware.SessionMiddleware',
67 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
68 | )
69 |
70 | ROOT_URLCONF = 'blog.urls'
71 |
72 | TEMPLATE_DIRS = (
73 | # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
74 | # Always use forward slashes, even on Windows.
75 | # Don't forget to use absolute paths, not relative paths.
76 | )
77 |
78 | INSTALLED_APPS = (
79 | 'django.contrib.auth',
80 | 'django.contrib.contenttypes',
81 | 'django.contrib.sessions',
82 | 'django.contrib.sites',
83 | 'app',
84 | 'blog',
85 | )
86 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templatetags/blog.py:
--------------------------------------------------------------------------------
1 | from django import template
2 | from django.conf import settings
3 | from django.db import models
4 |
5 | import re
6 |
7 | Post = models.get_model('blog', 'post')
8 | Category = models.get_model('blog', 'category')
9 |
10 | register = template.Library()
11 |
12 |
13 | class LatestPosts(template.Node):
14 | def __init__(self, limit, var_name):
15 | self.limit = limit
16 | self.var_name = var_name
17 |
18 | def render(self, context):
19 | posts = Post.objects.published()[:int(self.limit)]
20 | if posts and (int(self.limit) == 1):
21 | context[self.var_name] = posts[0]
22 | else:
23 | context[self.var_name] = posts
24 | return ''
25 |
26 | @register.tag
27 | def get_latest_posts(parser, token):
28 | """
29 | Gets any number of latest posts and stores them in a varable.
30 |
31 | Syntax::
32 |
33 | {% get_latest_posts [limit] as [var_name] %}
34 |
35 | Example usage::
36 |
37 | {% get_latest_posts 10 as latest_post_list %}
38 | """
39 | try:
40 | tag_name, arg = token.contents.split(None, 1)
41 | except ValueError:
42 | raise template.TemplateSyntaxError, "%s tag requires arguments" % token.contents.split()[0]
43 | m = re.search(r'(.*?) as (\w+)', arg)
44 | if not m:
45 | raise template.TemplateSyntaxError, "%s tag had invalid arguments" % tag_name
46 | format_string, var_name = m.groups()
47 | return LatestPosts(format_string, var_name)
48 |
49 |
50 | class BlogCategories(template.Node):
51 | def __init__(self, var_name):
52 | self.var_name = var_name
53 |
54 | def render(self, context):
55 | categories = Category.objects.all()
56 | context[self.var_name] = categories
57 | return ''
58 |
59 | @register.tag
60 | def get_blog_categories(parser, token):
61 | """
62 | Gets all blog categories.
63 |
64 | Syntax::
65 |
66 | {% get_blog_categories as [var_name] %}
67 |
68 | Example usage::
69 |
70 | {% get_blog_categories as category_list %}
71 | """
72 | try:
73 | tag_name, arg = token.contents.split(None, 1)
74 | except ValueError:
75 | raise template.TemplateSyntaxError, "%s tag requires arguments" % token.contents.split()[0]
76 | m = re.search(r'as (\w+)', arg)
77 | if not m:
78 | raise template.TemplateSyntaxError, "%s tag had invalid arguments" % tag_name
79 | var_name = m.groups()[0]
80 | return BlogCategories(var_name)
81 |
82 |
83 | @register.filter
84 | def get_links(value):
85 | """
86 | Extracts links from a ``Post`` body and returns a list.
87 |
88 | Template Syntax::
89 |
90 | {{ post.body|markdown:"safe"|get_links }}
91 |
92 | """
93 | try:
94 | try:
95 | from BeautifulSoup import BeautifulSoup
96 | except ImportError:
97 | from beautifulsoup import BeautifulSoup
98 | soup = BeautifulSoup(value)
99 | return soup.findAll('a')
100 | except ImportError:
101 | if settings.DEBUG:
102 | raise template.TemplateSyntaxError, "Error in 'get_links' filter: BeautifulSoup isn't installed."
103 | return value
104 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templatetags/.svn/text-base/blog.py.svn-base:
--------------------------------------------------------------------------------
1 | from django import template
2 | from django.conf import settings
3 | from django.db import models
4 |
5 | import re
6 |
7 | Post = models.get_model('blog', 'post')
8 | Category = models.get_model('blog', 'category')
9 |
10 | register = template.Library()
11 |
12 |
13 | class LatestPosts(template.Node):
14 | def __init__(self, limit, var_name):
15 | self.limit = limit
16 | self.var_name = var_name
17 |
18 | def render(self, context):
19 | posts = Post.objects.published()[:int(self.limit)]
20 | if posts and (int(self.limit) == 1):
21 | context[self.var_name] = posts[0]
22 | else:
23 | context[self.var_name] = posts
24 | return ''
25 |
26 | @register.tag
27 | def get_latest_posts(parser, token):
28 | """
29 | Gets any number of latest posts and stores them in a varable.
30 |
31 | Syntax::
32 |
33 | {% get_latest_posts [limit] as [var_name] %}
34 |
35 | Example usage::
36 |
37 | {% get_latest_posts 10 as latest_post_list %}
38 | """
39 | try:
40 | tag_name, arg = token.contents.split(None, 1)
41 | except ValueError:
42 | raise template.TemplateSyntaxError, "%s tag requires arguments" % token.contents.split()[0]
43 | m = re.search(r'(.*?) as (\w+)', arg)
44 | if not m:
45 | raise template.TemplateSyntaxError, "%s tag had invalid arguments" % tag_name
46 | format_string, var_name = m.groups()
47 | return LatestPosts(format_string, var_name)
48 |
49 |
50 | class BlogCategories(template.Node):
51 | def __init__(self, var_name):
52 | self.var_name = var_name
53 |
54 | def render(self, context):
55 | categories = Category.objects.all()
56 | context[self.var_name] = categories
57 | return ''
58 |
59 | @register.tag
60 | def get_blog_categories(parser, token):
61 | """
62 | Gets all blog categories.
63 |
64 | Syntax::
65 |
66 | {% get_blog_categories as [var_name] %}
67 |
68 | Example usage::
69 |
70 | {% get_blog_categories as category_list %}
71 | """
72 | try:
73 | tag_name, arg = token.contents.split(None, 1)
74 | except ValueError:
75 | raise template.TemplateSyntaxError, "%s tag requires arguments" % token.contents.split()[0]
76 | m = re.search(r'as (\w+)', arg)
77 | if not m:
78 | raise template.TemplateSyntaxError, "%s tag had invalid arguments" % tag_name
79 | var_name = m.groups()[0]
80 | return BlogCategories(var_name)
81 |
82 |
83 | @register.filter
84 | def get_links(value):
85 | """
86 | Extracts links from a ``Post`` body and returns a list.
87 |
88 | Template Syntax::
89 |
90 | {{ post.body|markdown:"safe"|get_links }}
91 |
92 | """
93 | try:
94 | try:
95 | from BeautifulSoup import BeautifulSoup
96 | except ImportError:
97 | from beautifulsoup import BeautifulSoup
98 | soup = BeautifulSoup(value)
99 | return soup.findAll('a')
100 | except ImportError:
101 | if settings.DEBUG:
102 | raise template.TemplateSyntaxError, "Error in 'get_links' filter: BeautifulSoup isn't installed."
103 | return value
104 |
--------------------------------------------------------------------------------
/fixture/test/test_dataset/test_converter.py:
--------------------------------------------------------------------------------
1 |
2 | from fixture.test import attr
3 | from decimal import Decimal
4 | import datetime
5 | from fixture import DataSet
6 | from nose.tools import eq_, raises
7 | from fixture.dataset.converter import *
8 | try:
9 | import json
10 | except ImportError:
11 | import simplejson as json
12 | from cStringIO import StringIO
13 |
14 | class FooData(DataSet):
15 | class bar:
16 | name = "call me bar"
17 | is_alive = False
18 | class foo:
19 | name = "name's foo"
20 | is_alive = True
21 |
22 | class MuchoData(DataSet):
23 | class mucho:
24 | d = datetime.date(2008,1,1)
25 | dt = datetime.datetime(2008,1,1,2,30,59)
26 | dec = Decimal("1.45667")
27 | fl = float(1.45667)
28 |
29 | class DummyError(Exception):
30 | pass
31 |
32 | class TestDatasetToJson(object):
33 |
34 | @attr(unit=1)
35 | @raises(TypeError)
36 | def test_must_be_dataset(self):
37 | class NotADataSet(object):
38 | pass
39 | dataset_to_json(NotADataSet)
40 |
41 | @attr(unit=1)
42 | def test_convert_cls(self):
43 | eq_(dataset_to_json(FooData),
44 | json.dumps(
45 | [{'name': "call me bar",
46 | 'is_alive': False},
47 | {'name': "name's foo",
48 | 'is_alive': True}]))
49 |
50 | @attr(unit=1)
51 | def test_convert_instance(self):
52 | foo = FooData()
53 | eq_(dataset_to_json(foo),
54 | json.dumps(
55 | [{'name': "call me bar",
56 | 'is_alive': False},
57 | {'name': "name's foo",
58 | 'is_alive': True}]))
59 |
60 | @attr(unit=1)
61 | def test_dump_to_file(self):
62 | fp = StringIO()
63 | dataset_to_json(FooData, fp=fp)
64 | eq_(fp.getvalue(),
65 | json.dumps(
66 | [{'name': "call me bar",
67 | 'is_alive': False},
68 | {'name': "name's foo",
69 | 'is_alive': True}]))
70 |
71 | @attr(unit=1)
72 | def test_types(self):
73 | eq_(json.loads(dataset_to_json(MuchoData)),
74 | [{
75 | 'd': "2008-01-01",
76 | "dt": "2008-01-01 02:30:59",
77 | "dec": "1.45667",
78 | "fl": 1.45667
79 | }])
80 |
81 | @attr(unit=1)
82 | @raises(DummyError)
83 | def test_custom_converter(self):
84 |
85 | def my_default(obj):
86 | raise DummyError()
87 |
88 | ds = dataset_to_json(MuchoData, default=my_default)
89 | assert not ds, (
90 | "dataset_to_json() should have died but it returned: %s" % ds)
91 |
92 | @attr(unit=1)
93 | def test_wrap(self):
94 |
95 | def wrap_in_dict(objects):
96 | return {'data': objects}
97 |
98 | eq_(dataset_to_json(FooData, wrap=wrap_in_dict),
99 | json.dumps({
100 | 'data':
101 | [{'name': "call me bar",
102 | 'is_alive': False},
103 | {'name': "name's foo",
104 | 'is_alive': True}]
105 | }))
106 |
--------------------------------------------------------------------------------
/fixture/test/test_loadable/test_django/fixture-with-django-doctests.rst:
--------------------------------------------------------------------------------
1 |
2 | .. _django-doctests:
3 |
4 | -----------------------------------
5 | Old django doctests
6 | -----------------------------------
7 |
8 | Back to :ref:`using-fixture-with-django`
9 |
10 | We'll be using a simple django project and application (found in fixture/examples/django_example/). The models.py is included here for reference:
11 |
12 | .. _doctest-models:
13 |
14 | .. literalinclude:: ../../fixture/examples/django_example/app/models.py
15 | :language: python
16 | :linenos:
17 |
18 | .. currentmodule:: fixture.loadable.django_loadable
19 |
20 | Given the above models and the following fixtures:
21 |
22 | .. doctest::
23 |
24 | >>> from fixture import DataSet
25 | >>> class AuthorData(DataSet):
26 | ... class Meta:
27 | ... django_model = 'app.Author'
28 | ... class frank_herbert:
29 | ... first_name = "Frank"
30 | ... last_name = "Herbert"
31 | ... class guido:
32 | ... first_name = "Guido"
33 | ... last_name = "Van rossum"
34 | ...
35 | >>> class BookData(DataSet):
36 | ... class Meta:
37 | ... django_model = 'app.Book'
38 | ... class dune:
39 | ... title = "Dune"
40 | ... author = AuthorData.frank_herbert
41 | ...
42 | ... class python:
43 | ... title = 'Python'
44 | ... author = AuthorData.guido
45 | ...
46 | >>> class ReviewerData(DataSet):
47 | ... class Meta:
48 | ... django_model = 'app.Reviewer'
49 | ... class ben:
50 | ... name = 'ben'
51 | ... reviewed = [BookData.dune, BookData.python]
52 |
53 | We can do the following:
54 |
55 | .. doctest::
56 |
57 | >>> from fixture import DjangoFixture
58 | >>> from django.db.models.loading import get_model, get_app
59 | >>> from fixture.test.test_loadable.test_django.util import assert_empty
60 | >>> app = get_app('app')
61 | >>> assert_empty(app)
62 | >>> Book = get_model('app', 'Book')
63 | >>> django_fixture = DjangoFixture()
64 | >>> data = django_fixture.data(BookData)
65 | >>> data.setup()
66 |
67 | All the books are here:
68 |
69 | .. doctest::
70 |
71 | >>> [(b.title, b.author.first_name) for b in Book.objects.all()]
72 | [(u'Dune', u'Frank'), (u'Python', u'Guido')]
73 |
74 | And fixture has pulled in all the Authors too:
75 |
76 | .. doctest::
77 |
78 | >>> Author = get_model('app', 'Author')
79 | >>> [a.first_name for a in Author.objects.all()]
80 | [u'Frank', u'Guido']
81 |
82 | But not the Reviewers:
83 |
84 | .. doctest::
85 |
86 | >>> get_model('app', 'Reviewer').objects.count()
87 | 0
88 |
89 | If we load the ReviewerDatas DataSet, all of the others will be pulled in:
90 |
91 | .. doctest::
92 |
93 | >>> data.teardown() # Get rid of the old data
94 | >>> assert_empty(app)
95 |
96 |
97 | .. doctest::
98 |
99 | >>> data = django_fixture.data(ReviewerData)
100 | >>> data.setup()
101 | >>> get_model('app', 'Reviewer').objects.count()
102 | 1
103 | >>> Book.objects.count()
104 | 2
105 | >>> Author.objects.count()
106 | 2
107 | >>> data.teardown()
108 |
109 |
110 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/.svn/text-base/CHANGELOG.yml.svn-base:
--------------------------------------------------------------------------------
1 | changes:
2 | date: 2008-09-17
3 | change: Enabled the ability to override the default template names.
4 |
5 | date: 2008-08-26
6 | change: Upgraded post_detail.html to now use new Django refactored comments. Sidenote: basic.remarks have been removed.
7 |
8 | date: 2008-07-14
9 | change: Removed get_query_set from Blog manager to fix a problem where saving a post marked as Draft would not save.
10 | change: Added a get_previous_post and get_next_post method for front end template. These will not return Draft posts.
11 |
12 | date: 2008-06-17
13 | change: BlogPostFeed is now BlogPostsFeed and there is a new BlogPostsByCategory.
14 |
15 | date: 2008-05-18
16 | change: Converted everything to 4 space tabs and made a few other changes to comply with Python Style Guide.
17 |
18 | date: 2008-04-23
19 | change: Added an inline admin interface helper for choosing inlines to go into posts.
20 | change: The inline app is now a dependancy of the blog.
21 |
22 | date: 2008-04-22
23 | change: Removed the 'render_inlines' filter from the Blog template tags. The tag is now in an app called inlines which can be used with any django app.
24 |
25 | date: 2008-02-27
26 | change: Added 'allow_comments' field to the Post model.
27 | change: Removed 'Closed' choice from status field of Post model
28 |
29 | date: 2008-02-18
30 | fix: Fixed feed pointing to hardcoded url.
31 |
32 | date: 2008-02-15
33 | change: Internationalized models
34 |
35 | date: 2008-02-04
36 | change: Added 'get_links' template filter.
37 | change: Templates: added a {% block content_title %}
38 |
39 | date: 2008-02-02
40 | change: Added a sitemap
41 |
42 | date: 2008-01-30
43 | change: Renamed 'do_inlines' filter to 'render_inlines'
44 |
45 | date: 2008-01-29
46 | change: BeautifulSoup is no longer a dependancy unless you want to use the do_inlines filter.
47 |
48 | date: 2008-01-27
49 | fix: removed 'tagging.register(Post)' from model. It was causing too many unnecessary SQL JOINS.
50 | change: Changed the inlines tag to a filter. (Example: {{ object.text|do_inlines }})
51 |
52 | date: 2008-01-22
53 | change: Registered the Post model with the tagging app
54 |
55 | date: 2008-01-19
56 | change: Renamed the 'list' class to 'link_list'
57 |
58 | date: 2008-01-09
59 | change: Changed urls.py so you can have /posts/page/2/ or /posts/?page=2
60 |
61 | date: 2008-01-07
62 | change: Removed PublicPostManager in favor of ManagerWithPublished.
63 | change: Made wrappers for generic views.
64 |
65 | date: 2008-01-06
66 | fix: In blog.py changed 'beautifulsoup' to 'BeautifulSoup'
67 |
68 | date: 2007-12-31
69 | change: Changed some syntax in managers.py to hopefully fix a bug.
70 | change: Removed an inline template that didn't belong.
71 |
72 | date: 2007-12-21
73 | change: Added markup tag that formats inlines.
74 |
75 | date: 2007-12-12
76 | change: Cleaned up unit tests.
77 |
78 | date: 2007-12-11
79 | change: Add documentation to templatetags and views.
80 | change: Smartened up the previous/next blog part of the post_detail.html template.
81 |
82 | date: 2007-12-09
83 | change: Added feed templates and wrapped up feeds.py.
84 | change: Changed Post.live manager to Post.public
85 | change: Added a search view along with templates
86 |
--------------------------------------------------------------------------------
/fixture/test/__init__.py:
--------------------------------------------------------------------------------
1 |
2 | """The fixture test suite.
3 |
4 | There are several things to build before you can run the tests.
5 | Hopefully this will be simplified in the future but for now, do this:
6 |
7 | Create the buildout::
8 |
9 | $ python2.5 setup_test_buildout.py
10 |
11 | Check out the trunk of Django (until 1.1 is released) into a src dir for buildout ::
12 |
13 | $ svn co http://code.djangoproject.com/svn/django/trunk/ src/django
14 |
15 | Build everything ::
16 |
17 | $ ./bin/buildout
18 |
19 | Run syncdb on the Django test DB and create a superuser ::
20 |
21 | $ ./bin/manage syncdb
22 |
23 | Run the tests ::
24 |
25 | $ ./bin/test-fixture
26 |
27 | Environment Variables
28 | ---------------------
29 |
30 | The test suite is affected by several environment variables:
31 |
32 | - FIXTURE_TEST_HEAVY_DSN
33 |
34 | - a database connection that can support operations like foreign key relations
35 | (sqlite won't through foreign key errors)
36 | - defaults to None.
37 | - typically this would be a postgres connection where temp tables can be
38 | created and destroyed
39 | - a special DSN, "sqlite:///:tmp:", will create a connection to a temporary
40 | file-based sqlite db. This is necessary because :memory: dbs can't be
41 | shared easily using sqlalchemy (connections are not pooled)
42 |
43 | - FIXTURE_TEST_LITE_DSN
44 |
45 | - a database as lite as possible, for speed
46 | - defaults to sqlite:///:memory:
47 |
48 | As a shortcut, you can run this to set these variables in your shell ::
49 |
50 | $ source fixture/test/profile/full.sh
51 |
52 | """
53 |
54 | import unittest, nose, os
55 | from fixture.test import conf
56 |
57 | def setup():
58 | # super hack:
59 | if conf.HEAVY_DSN == 'sqlite:///:tmp:':
60 | conf.HEAVY_DSN_IS_TEMPIO = True
61 | conf.reset_heavy_dsn()
62 |
63 | # this is here because the doc generator also runs doctests.
64 | # should fix that to use proper _test() methods for a module
65 | teardown_examples()
66 |
67 | def teardown():
68 | teardown_examples()
69 |
70 | def teardown_examples():
71 | if os.path.exists('/tmp/fixture_example.db'):
72 | os.unlink('/tmp/fixture_example.db')
73 | if os.path.exists('/tmp/fixture_generate.db'):
74 | os.unlink('/tmp/fixture_generate.db')
75 |
76 |
77 | class PrudentTestResult(unittest.TestResult):
78 | """A test result that raises an exception immediately"""
79 | def _raise_err(self, err):
80 | exctype, value, tb = err
81 | raise Exception("%s: %s" % (exctype, value)), None, tb
82 |
83 | def addFailure(self, test, err):
84 | self._raise_err(err)
85 | def addError(self, test, err):
86 | self._raise_err(err)
87 |
88 | class _SilentTestResult(PrudentTestResult):
89 | def printErrors(self):
90 | pass
91 | def printErrorList(self, flavour, errors):
92 | pass
93 |
94 | class SilentTestRunner(unittest.TextTestRunner):
95 | """a test runner that doesn't print output but raises
96 | exceptions immediately
97 | """
98 | def _makeResult(self):
99 | return _SilentTestResult()
100 |
101 | def run(self, test):
102 | "Run the given test case or test suite."
103 | result = self._makeResult()
104 | test(result)
105 | return result
106 |
107 | def attr(**kwargs):
108 | """Add attributes to a test function/method/class"""
109 | def wrap(func):
110 | func.__dict__.update(kwargs)
111 | return func
112 | return wrap
113 |
114 |
115 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/templates/blog/.svn/entries:
--------------------------------------------------------------------------------
1 | 9
2 |
3 | dir
4 | 102
5 | http://django-basic-apps.googlecode.com/svn/trunk/blog/templates/blog
6 | http://django-basic-apps.googlecode.com/svn
7 |
8 |
9 |
10 | 2008-10-06T01:31:58.796932Z
11 | 83
12 | nathan@playgroundblues.com
13 |
14 |
15 | svn:special svn:externals svn:needs-lock
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 5ae32e2a-df40-0410-a01d-45158a99d8df
28 |
29 | base_blog.html
30 | file
31 |
32 |
33 |
34 |
35 | 2009-03-04T15:11:18.000000Z
36 | b9986c0b0e12f6f0e39be84d9a393375
37 | 2008-04-27T15:53:25.835450Z
38 | 32
39 | nathan@playgroundblues.com
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | 68
62 |
63 | category_detail.html
64 | file
65 |
66 |
67 |
68 |
69 | 2009-03-04T15:11:18.000000Z
70 | d1850d7ac8182c538b91ed4074cc4b9d
71 | 2008-10-06T01:31:58.796932Z
72 | 83
73 | nathan@playgroundblues.com
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | 668
96 |
97 | post_list.html
98 | file
99 |
100 |
101 |
102 |
103 | 2009-03-04T15:11:18.000000Z
104 | f2cad2bbc52296d70a217f574f196558
105 | 2008-10-06T01:31:58.796932Z
106 | 83
107 | nathan@playgroundblues.com
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 | 866
130 |
131 | post_archive_day.html
132 | file
133 |
134 |
135 |
136 |
137 | 2009-03-04T15:11:18.000000Z
138 | ddce1084c8d3344c423b4e9cf85047e8
139 | 2008-10-06T01:31:58.796932Z
140 | 83
141 | nathan@playgroundblues.com
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 | 607
164 |
165 | post_archive_year.html
166 | file
167 |
168 |
169 |
170 |
171 | 2009-03-04T15:11:18.000000Z
172 | ea695ee6a108d20ebb7f691621c6bfe9
173 | 2008-10-06T01:31:58.796932Z
174 | 83
175 | nathan@playgroundblues.com
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 | 494
198 |
199 | post_detail.html
200 | file
201 |
202 |
203 |
204 |
205 | 2009-03-04T15:11:18.000000Z
206 | 7547f3497a66a8a8384b77a90f8fc7cb
207 | 2008-10-06T01:31:58.796932Z
208 | 83
209 | nathan@playgroundblues.com
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | 2238
232 |
233 | category_list.html
234 | file
235 |
236 |
237 |
238 |
239 | 2009-03-04T15:11:18.000000Z
240 | f5034dbc2454b0024c90a50ed6e6416b
241 | 2008-10-06T01:31:58.796932Z
242 | 83
243 | nathan@playgroundblues.com
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 | 441
266 |
267 | post_search.html
268 | file
269 |
270 |
271 |
272 |
273 | 2009-03-04T15:11:18.000000Z
274 | d1ab8c7e13584d9bd21d0cd14d29be0e
275 | 2008-10-06T01:31:58.796932Z
276 | 83
277 | nathan@playgroundblues.com
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 | 989
300 |
301 | post_archive_month.html
302 | file
303 |
304 |
305 |
306 |
307 | 2009-03-04T15:11:18.000000Z
308 | f13c119ed586afc5beb7b1af117517e9
309 | 2008-10-06T01:31:58.796932Z
310 | 83
311 | nathan@playgroundblues.com
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 | 609
334 |
335 |
--------------------------------------------------------------------------------
/docs/source/using-fixture-cmd.rst:
--------------------------------------------------------------------------------
1 | .. _using-fixture-command:
2 |
3 | -------------------------
4 | Using the fixture command
5 | -------------------------
6 |
7 | .. contents:: :local:
8 |
9 | There are several issues you may run into while working with fixtures:
10 |
11 | 1. The data model of a program is usually an implementation detail. It's bad practice to "know" about implementation details in tests because it means you have to update your tests when those details change; you should only have to update your tests when an interface changes.
12 | 2. Data accumulates very fast and there is already a useful tool for slicing and dicing data: the database! Hand-coding DataSet classes is not always the way to go.
13 | 3. When regression testing or when trying to reproduce a bug, you may want to grab a "snapshot" of the existing data.
14 |
15 | ``fixture`` is a shell command to address these and other issues. It gets installed along with this module. Specifically, the ``fixture`` command accepts a path to a single object and queries that object using the command options. The output is python code that you can use in a test to reload the data retrieved by the query.
16 |
17 | .. note:: WARNING: This feature is not fully implemented and doesn't support all backends.
18 |
19 | Usage
20 | ~~~~~
21 |
22 | .. shell::
23 | :run_on_method: fixture.command.generate.main
24 |
25 | fixture --help
26 |
27 | An Example With SQLAlchemy
28 | ~~~~~~~~~~~~~~~~~~~~~~~~~~
29 |
30 | Here is a data model defined in `SQLAlchemy `_ code. (For complete code see ``fixture/examples/db/sqlalchemy_examples.py``.)
31 |
32 | .. doctest:: command
33 |
34 | >>> from sqlalchemy import *
35 | >>> from sqlalchemy.orm import *
36 | >>> metadata = MetaData()
37 | >>> authors = Table('authors', metadata,
38 | ... Column('id', Integer, primary_key=True),
39 | ... Column('first_name', String(100)),
40 | ... Column('last_name', String(100)))
41 | ...
42 | >>> class Author(object):
43 | ... pass
44 | ...
45 | >>> books = Table('books', metadata,
46 | ... Column('id', Integer, primary_key=True),
47 | ... Column('title', String(100)),
48 | ... Column('author_id', Integer, ForeignKey('authors.id')))
49 | ...
50 | >>> class Book(object):
51 | ... pass
52 | ...
53 | >>> def setup_mappers():
54 | ... mapper(Author, authors)
55 | ... mapper(Book, books, properties={
56 | ... 'author': relation(Author)
57 | ... })
58 | ...
59 | >>> def connect(dsn):
60 | ... metadata.bind = create_engine(dsn)
61 | ...
62 | >>>
63 |
64 | After inserting some data, it would be possible to run a command that points at the ``Book`` object. The above command uses ``Book`` to send a select query with a where clause ``WHERE title='Dune'``, and turns the record sets into ``DataSet`` classes:
65 |
66 | .. shell::
67 | :setup: fixture.docs.setup_command_data
68 | :teardown: fixture.test.teardown_examples
69 |
70 | fixture fixture.examples.db.sqlalchemy_examples.Book \
71 | --dsn=sqlite:////tmp/fixture_example.db \
72 | --where="title='Dune'" \
73 | --connect=fixture.examples.db.sqlalchemy_examples:connect \
74 | --setup=fixture.examples.db.sqlalchemy_examples:setup_mappers
75 |
76 | Notice that we queried the ``Book`` object but got back Table objects. Also notice that all foreign keys were followed to reproduce the complete chain of data (in this case, the ``authors`` table data).
77 |
78 | Also notice that several hooks were used, one to connect the ``metadata`` object by DSN and another to setup the mappers. See *Usage* above for more information on the ``--connect`` and ``--setup`` options.
79 |
80 | Creating a custom data handler
81 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
82 |
83 | No documentation yet
84 |
--------------------------------------------------------------------------------
/fixture/test/test_command/test_generate/__init__.py:
--------------------------------------------------------------------------------
1 |
2 | import sys
3 | import os
4 | from nose.tools import eq_
5 | from nose.exc import SkipTest
6 | from fixture.test import conf
7 | from fixture.command.generate import DataSetGenerator, dataset_generator
8 |
9 | def setup():
10 | # every tests needs a real db conn :
11 | if not conf.HEAVY_DSN:
12 | raise SkipTest
13 |
14 | def compile_(code):
15 | """compiles code string for a module.
16 |
17 | returns dict w/ attributes of that module.
18 | """
19 | mod = {}
20 | eval(compile(code, 'stdout', 'exec'), mod)
21 | return mod
22 |
23 | class GenerateTest(object):
24 | """tests that a fixture code generator can run with the specified arguments
25 | and produce a loadable fixture.
26 |
27 | the details of which arguments, how that fixture loads data, and how the
28 | data load is proven is defined in the concrete implementation of this test
29 | class
30 |
31 | """
32 | args = []
33 |
34 | def __init__(self, *a, **kw):
35 | super(GenerateTest, self).__init__(*a, **kw)
36 | self.env = None
37 |
38 | def assert_env_is_clean(self):
39 | raise NotImplementedError
40 |
41 | def assert_env_generated_ok(self, env):
42 | raise NotImplementedError
43 |
44 | def assert_data_loaded(self, data):
45 | raise NotImplementedError
46 |
47 | def create_fixture(self):
48 | raise NotImplementedError("must return a concrete LoadableFixture instance, i.e. SQLAlchemyFixture")
49 |
50 | def load_env(self, module):
51 | raise NotImplementedError
52 |
53 | def dataset_generator(self, extra_args=[]):
54 | args = [a for a in self.args]
55 | if extra_args:
56 | args.extend(extra_args)
57 |
58 | self.assert_env_is_clean()
59 | code = dataset_generator(args)
60 | try:
61 | self.env = compile_(code)
62 | self.assert_env_generated_ok(self.env)
63 | data = self.load_env(self.env)
64 | self.assert_data_loaded(data)
65 | except:
66 | print code
67 | raise
68 |
69 | def test_query(self):
70 | self.dataset_generator(['-w', "name = 'super cash back!'"])
71 |
72 | def test_query_no_data(self):
73 | _stderr = sys.stderr
74 | sys.stderr = sys.stdout
75 | def wrong_exc(exc=None):
76 | raise AssertionError("expected exit 2 %s" % (
77 | exc and ("(raised: %s: %s)" % (exc.__class__, exc)) or ""))
78 | try:
79 | try:
80 | self.dataset_generator(['-w', "name = 'fooobzarius'"])
81 | except SystemExit, e:
82 | eq_(e.code, 2)
83 | except Exception, e:
84 | wrong_exc(e)
85 | else:
86 | wrong_exc()
87 | finally:
88 | sys.stderr = _stderr
89 |
90 |
91 | class UsingTesttoolsTemplate(object):
92 | def __init__(self, *a,**kw):
93 | super(UsingTesttoolsTemplate, self).__init__(*a,**kw)
94 | self.args = [a for a in self.args] + ["--template=testtools"]
95 |
96 | def load_datasets(self, module, datasets):
97 | from testtools.fixtures import affix
98 | fxt = affix(*[d() for d in datasets])
99 | return fxt
100 |
101 | class UsingFixtureTemplate(object):
102 | def __init__(self, *a,**kw):
103 | super(UsingFixtureTemplate, self).__init__(*a,**kw)
104 | self.args = [a for a in self.args] + ["--template=fixture"]
105 |
106 | def visit_loader(self, loader):
107 | pass
108 |
109 | def load_datasets(self, module, datasets):
110 | fixture = self.create_fixture()
111 | self.visit_loader(fixture.loader)
112 | d = fixture.data(*datasets)
113 | d.setup()
114 | return d
--------------------------------------------------------------------------------
/fixture/dataset/converter.py:
--------------------------------------------------------------------------------
1 |
2 | """Utilities for converting datasets."""
3 |
4 | import datetime
5 | import decimal
6 | import types
7 | from fixture.dataset import DataSet, DataRow
8 | json = None
9 | try:
10 | # 2.6
11 | import json
12 | except ImportError:
13 | try:
14 | import simplejson as json
15 | except ImportError:
16 | pass
17 |
18 | def _obj_items(obj):
19 | for name in dir(obj):
20 | if name.startswith('__'):
21 | continue
22 | yield name, getattr(obj, name)
23 |
24 | def default_json_converter(obj):
25 | """converts obj to a value safe for JSON serialization."""
26 | if isinstance(obj, (datetime.date, datetime.datetime, decimal.Decimal, float)):
27 | return str(obj)
28 | raise TypeError("%r is not JSON serializable" % (obj,))
29 |
30 | def dataset_to_json(dataset, fp=None, default=default_json_converter, wrap=None):
31 | """Converts a :class:`DataSet ` class or
32 | instance to JSON (JavaScript Object Notation).
33 |
34 | See :ref:`using-dataset-to-json` for detailed usage.
35 |
36 | Keyword Arguments
37 |
38 | **fp**
39 | An optional file-like object (must implement ``fp.write()``). When
40 | this is not None, the output is written to the fp object, otherwise
41 | the output is returned
42 |
43 | **default**
44 | A callable that takes one argument (an object) and returns output
45 | suitable for JSON serialization. This will *only* be called if the
46 | object cannot be serialized. For example::
47 |
48 | >>> def encode_complex(obj):
49 | ... if isinstance(obj, complex):
50 | ... return [obj.real, obj.imag]
51 | ... raise TypeError("%r is not JSON serializable" % (o,))
52 | ...
53 | >>> from fixture import DataSet
54 | >>> class ComplexData(DataSet):
55 | ... class math_stuff:
56 | ... complex = 2 + 1j
57 | ...
58 | >>> dataset_to_json(ComplexData, default=encode_complex)
59 | '[{"complex": [2.0, 1.0]}]'
60 |
61 | **wrap**
62 | A callable that takes one argument, the list of dictionaries before
63 | they are converted to JSON. For example::
64 |
65 | >>> def wrap_in_dict(objects):
66 | ... return {'data': objects}
67 | ...
68 | >>> from fixture import DataSet
69 | >>> class ColorData(DataSet):
70 | ... class red:
71 | ... color = "red"
72 | ...
73 | >>> dataset_to_json(ColorData, wrap=wrap_in_dict)
74 | '{"data": [{"color": "red"}]}'
75 |
76 | Returns a JSON encoded string unless you specified the **fp** keyword
77 |
78 | """
79 | assert json, (
80 | "You must have the simplejson or json module installed. "
81 | "Neither could be imported")
82 | if isinstance(dataset, type):
83 | # we got a class so make it an instance
84 | # so that rows are resolved
85 | dataset = dataset()
86 | if not isinstance(dataset, DataSet):
87 | raise TypeError("First argument must be a class or instance of a DataSet")
88 | objects = []
89 | for name, row in _obj_items(dataset):
90 | try:
91 | if not issubclass(row, DataRow):
92 | continue
93 | except TypeError:
94 | continue
95 | row_dict = {}
96 | for col, val in _obj_items(row):
97 | if col=='_reserved_attr' or callable(val):
98 | continue
99 | row_dict[col] = val
100 | objects.append(row_dict)
101 | if wrap:
102 | objects = wrap(objects)
103 | if fp:
104 | return json.dump(objects, fp, default=default)
105 | else:
106 | return json.dumps(objects, default=default)
107 |
108 | if __name__ == '__main__':
109 | import doctest
110 | doctest.testmod()
--------------------------------------------------------------------------------
/fixture/test/test_command/test_generate/test_generate_sqlobject.py:
--------------------------------------------------------------------------------
1 |
2 | import os
3 | from nose.tools import eq_
4 | from nose.exc import SkipTest
5 | from fixture import SQLObjectFixture
6 | from fixture.command.generate import DataSetGenerator, dataset_generator
7 | from fixture.dataset import MergedSuperSet
8 | from fixture.style import NamedDataStyle
9 | from fixture.test.test_command.test_generate import (
10 | compile_, GenerateTest, UsingTesttoolsTemplate, UsingFixtureTemplate)
11 | from fixture.test import env_supports, conf
12 | from fixture.examples.db.sqlobject_examples import (
13 | Category, Product, Offer, setup_db, teardown_db)
14 |
15 | sqlhub = None
16 | realconn = None
17 | memconn = None
18 |
19 | def setup():
20 | global memconn, realconn, sqlhub
21 | if not env_supports.sqlobject:
22 | raise SkipTest
23 |
24 | from sqlobject import connectionForURI, sqlhub
25 |
26 | realconn = connectionForURI(conf.HEAVY_DSN)
27 | memconn = connectionForURI("sqlite:/:memory:")
28 |
29 | def teardown():
30 | realconn.close()
31 | globals()['realconn'] = None
32 | memconn.close()
33 | globals()['memconn'] = None
34 |
35 | class SQLObjectGenerateTest(GenerateTest):
36 | args = [
37 | "fixture.examples.db.sqlobject_examples.Offer",
38 | "--dsn", str(conf.HEAVY_DSN) ]
39 |
40 | def assert_data_loaded(self, fxt):
41 | rs = Category.select()
42 | eq_(rs.count(), 2)
43 | parkas = rs[0]
44 | rebates = rs[1]
45 | eq_(parkas.name, "parkas")
46 | eq_(rebates.name, "rebates")
47 |
48 | rs = Product.select()
49 | eq_(rs.count(), 1)
50 | eq_(rs[0].name, "jersey")
51 |
52 | rs = Offer.select()
53 | eq_(rs.count(), 1)
54 | eq_(rs[0].name, "super cash back!")
55 |
56 | # note that here we test that colliding fixture key links
57 | # got resolved correctly :
58 | eq_(Category.get(fxt.product_1.category_id), parkas)
59 | eq_(Category.get(fxt.offer_1.category_id), rebates)
60 |
61 | def assert_env_is_clean(self):
62 | # sanity check :
63 | assert Product.select(connection=realconn).count()
64 | assert not Product.select(connection=memconn).count()
65 |
66 | def assert_env_generated_ok(self, e):
67 | CategoryData = e['CategoryData']
68 | ProductData = e['ProductData']
69 | OfferData = e['OfferData']
70 |
71 | # another sanity check, wipe out the source data
72 | Offer.clearTable(connection=realconn)
73 | Product.clearTable(connection=realconn)
74 | Category.clearTable(connection=realconn)
75 |
76 | def create_fixture(self):
77 | return SQLObjectFixture(
78 | env = self.env,
79 | style = NamedDataStyle(),
80 | dataclass = MergedSuperSet,
81 | )
82 |
83 | def load_datasets(self, module, conn, datasets):
84 | raise NotImplementedError
85 |
86 | def load_env(self, env):
87 | # set our conn back to memory then load the fixture.
88 | # hmm, seems hoky
89 | sqlhub.processConnection = memconn
90 | data = self.load_datasets(env,
91 | [env['CategoryData'], env['ProductData'], env['OfferData']])
92 | return data
93 |
94 | def setUp(self):
95 | setup_db(realconn)
96 | sqlhub.processConnection = realconn
97 |
98 | parkas = Category(name="parkas")
99 | jersey = Product(name="jersey", category=parkas)
100 | rebates = Category(name="rebates")
101 | super_cashback = Offer( name="super cash back!",
102 | product=jersey, category=rebates)
103 | sqlhub.processConnection = None
104 |
105 | # now get the loading db as a sqlite mem connection :
106 | setup_db(memconn)
107 |
108 | def tearDown(self):
109 | sqlhub.processConnection = None
110 | teardown_db(realconn)
111 | teardown_db(memconn)
112 |
113 | class TestSQLObjectTesttools(UsingTesttoolsTemplate, SQLObjectGenerateTest):
114 | pass
115 |
116 | class TestSQLObjectFixture(UsingFixtureTemplate, SQLObjectGenerateTest):
117 | def visit_loader(self, loader):
118 | loader.connection = memconn
119 |
120 |
--------------------------------------------------------------------------------
/fixture/examples/django_example/blog/.svn/entries:
--------------------------------------------------------------------------------
1 | 9
2 |
3 | dir
4 | 102
5 | http://django-basic-apps.googlecode.com/svn/trunk/blog
6 | http://django-basic-apps.googlecode.com/svn
7 |
8 |
9 |
10 | 2009-01-23T18:24:47.940314Z
11 | 100
12 | nathan@playgroundblues.com
13 |
14 |
15 | svn:special svn:externals svn:needs-lock
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 5ae32e2a-df40-0410-a01d-45158a99d8df
28 |
29 | admin.py
30 | file
31 |
32 |
33 |
34 |
35 | 2009-03-04T15:11:19.000000Z
36 | dee1ad0e6d7452f90112602a2974d54c
37 | 2008-07-19T05:34:54.894082Z
38 | 54
39 | nathan@playgroundblues.com
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | 465
62 |
63 | views.py
64 | file
65 |
66 |
67 |
68 |
69 | 2009-03-04T15:11:19.000000Z
70 | 379961557784d427d46c3dcf072c4729
71 | 2008-10-16T20:54:22.265570Z
72 | 92
73 | nathan@playgroundblues.com
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | 6260
96 |
97 | managers.py
98 | file
99 |
100 |
101 |
102 |
103 | 2009-03-04T15:11:19.000000Z
104 | 4da04472e778f6fa4d09f77709a52622
105 | 2008-10-15T16:18:25.512182Z
106 | 91
107 | nathan@playgroundblues.com
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 | 272
130 |
131 | __init__.py
132 | file
133 |
134 |
135 |
136 |
137 | 2009-03-04T15:11:19.000000Z
138 | d41d8cd98f00b204e9800998ecf8427e
139 | 2008-03-27T00:51:14.650785Z
140 | 2
141 | nathan@playgroundblues.com
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 | 0
164 |
165 | CHANGELOG.yml
166 | file
167 |
168 |
169 |
170 |
171 | 2009-03-04T15:11:19.000000Z
172 | e57bdbfe15d62b49836728e36fe1fc2a
173 | 2008-09-17T17:07:56.790973Z
174 | 70
175 | nathan@playgroundblues.com
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 | 3252
198 |
199 | sitemap.py
200 | file
201 |
202 |
203 |
204 |
205 | 2009-03-04T15:11:19.000000Z
206 | 698a38257b08aed5f449b0435b1c7a0c
207 | 2008-05-18T17:37:22.333574Z
208 | 39
209 | nathan@playgroundblues.com
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | 278
232 |
233 | tests.py
234 | file
235 |
236 |
237 |
238 |
239 | 2009-03-04T15:11:19.000000Z
240 | 425a601d5f1a5df84eeb8b5d2eaac456
241 | 2008-11-12T02:37:11.794388Z
242 | 94
243 | nathan@playgroundblues.com
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 | 1962
266 |
267 | templatetags
268 | dir
269 |
270 | models.py
271 | file
272 |
273 |
274 |
275 |
276 | 2009-03-04T15:11:19.000000Z
277 | a7ec56cc39339200eb74fc590e58afec
278 | 2008-09-02T16:40:48.316008Z
279 | 63
280 | nathan@playgroundblues.com
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 | 2664
303 |
304 | README.txt
305 | file
306 |
307 |
308 |
309 |
310 | 2009-03-04T15:11:19.000000Z
311 | 7f4894c170b0c0cd5eeca63d69215ce8
312 | 2009-01-23T18:24:47.940314Z
313 | 100
314 | nathan@playgroundblues.com
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 | 873
337 |
338 | urls.py
339 | file
340 |
341 |
342 |
343 |
344 | 2009-03-04T15:11:19.000000Z
345 | b49132e6416b14894ad3b7d3b2d510f6
346 | 2008-09-17T17:07:56.790973Z
347 | 70
348 | nathan@playgroundblues.com
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 | 1139
371 |
372 | feeds.py
373 | file
374 |
375 |
376 |
377 |
378 | 2009-03-04T15:11:19.000000Z
379 | aa9b874c68a3551f4f5270af4053dcc2
380 | 2008-06-17T16:01:59.652184Z
381 | 50
382 | nathan@playgroundblues.com
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 | 1209
405 |
406 | templates
407 | dir
408 |
409 |
--------------------------------------------------------------------------------
/fixture/loadable/sqlobject_loadable.py:
--------------------------------------------------------------------------------
1 |
2 | """Components for loading and unloading data using `SQLObject`_.
3 |
4 | See :ref:`Using LoadableFixture` for examples.
5 |
6 | .. _SQLObject: http://www.sqlobject.org/
7 |
8 | """
9 |
10 | from fixture.loadable import DBLoadableFixture
11 |
12 | class SQLObjectMedium(DBLoadableFixture.StorageMediumAdapter):
13 | """
14 | Adapter for storing data using `SQLObject`_ classes
15 | """
16 | def clear(self, obj):
17 | """Delete this object from the DB"""
18 | obj.destroySelf()
19 |
20 | def save(self, row, column_vals):
21 | """Save this row to the DB"""
22 | from sqlobject.styles import getStyle
23 | so_style = getStyle(self.medium)
24 |
25 | if hasattr(row, 'connection'):
26 | raise ValueError(
27 | "cannot name a key 'connection' in row %s" % row)
28 | dbvals = dict([(so_style.dbColumnToPythonAttr(k), v)
29 | for k,v in column_vals])
30 | dbvals['connection'] = self.transaction
31 | return self.medium(**dbvals)
32 |
33 | def visit_loader(self, loader):
34 | """Visit the loader and store a reference to the transaction connection"""
35 | self.transaction = loader.transaction
36 |
37 | class SQLObjectFixture(DBLoadableFixture):
38 | """
39 | A fixture that knows how to load DataSet objects via `SQLObject`_ classes.
40 |
41 | >>> from fixture import SQLObjectFixture
42 |
43 | Keyword Arguments:
44 |
45 | ``style``
46 | A :class:`Style ` object to translate names with
47 |
48 | ``env``
49 | A dict or module that contains `SQLObject`_ classes. The :class:`Style ` object will
50 | look here when translating DataSet names into `SQLObject`_ class names.
51 | See :meth:`EnvLoadableFixture.attach_storage_medium ` for details on
52 | how ``env`` works.
53 |
54 | ``dsn``
55 | A dsn to create a connection with.
56 |
57 | ``dataclass``
58 | :class:`SuperSet ` class to represent loaded data with
59 |
60 | ``medium``
61 | A custom :class:`StorageMediumAdapter ` to instantiate when storing a DataSet.
62 |
63 | ``use_transaction``
64 | If this is true (default), data will be loaded or torn down inside a
65 | transaction. You may have to set this to false to avoid deadlocks.
66 | However, setting it to false may leave partially loaded data behind
67 | if you create an error with your DataSet.
68 |
69 | ``close_conn``
70 | True if the connection can be closed, helpful for releasing connections.
71 | If you are passing in a connection object this will be False by default.
72 |
73 | """
74 |
75 | def __init__(self, connection=None, use_transaction=True,
76 | close_conn=False, **kw ):
77 | DBLoadableFixture.__init__(self, **kw)
78 | self.connection = connection
79 | self.close_conn = close_conn
80 | self.use_transaction = use_transaction
81 |
82 | SQLObjectMedium = SQLObjectMedium
83 | Medium = SQLObjectMedium
84 |
85 | def create_transaction(self):
86 | """Return a new transaction for connection"""
87 | from sqlobject import connectionForURI
88 | if not self.connection:
89 | self.connection = connectionForURI(self.dsn)
90 | self.close_conn = True # because we made it
91 | if self.use_transaction:
92 | return self.connection.transaction()
93 | else:
94 | return self.connection
95 |
96 | def commit(self):
97 | """Commit transaction"""
98 | if self.use_transaction:
99 | DBLoadableFixture.commit(self)
100 |
101 | def then_finally(self, unloading=False):
102 | """Unconditionally close the transaction (if configured to do so) after loading data"""
103 | if unloading and self.close_conn:
104 | self.connection.close()
105 | self.connection = None # necessary for gc
106 |
107 | def rollback(self):
108 | """Rollback the transaction"""
109 | if self.use_transaction:
110 | DBLoadableFixture.rollback(self)
111 |
--------------------------------------------------------------------------------
/fixture/test/test_loadable/test_sqlobject_loadable.py:
--------------------------------------------------------------------------------
1 |
2 | import os, sys
3 | from nose.tools import eq_
4 | from nose.exc import SkipTest
5 | from fixture import SQLObjectFixture
6 | from fixture.test import env_supports
7 | from fixture import (
8 | SQLObjectFixture, NamedDataStyle, PaddedNameStyle, CamelAndUndersStyle,
9 | DataSet)
10 | from fixture.dataset import MergedSuperSet
11 | from fixture.test.test_loadable import *
12 | from fixture.examples.db.sqlobject_examples import *
13 | from fixture.test import conf
14 |
15 | def setup():
16 | if not env_supports.sqlobject: raise SkipTest
17 |
18 | class SQLObjectFixtureTest:
19 | fixture = SQLObjectFixture(
20 | style=( NamedDataStyle() + CamelAndUndersStyle()),
21 | dsn=conf.LITE_DSN, env=globals(),
22 | use_transaction=False,
23 | dataclass=MergedSuperSet )
24 |
25 | def setUp(self, dsn=conf.LITE_DSN):
26 | """should load the dataset"""
27 | from sqlobject import connectionForURI
28 | self.conn = connectionForURI(dsn)
29 | self.fixture.connection = self.conn
30 |
31 | from sqlobject import sqlhub
32 | sqlhub.processConnection = self.conn
33 |
34 | setup_db(self.conn)
35 |
36 | def tearDown(self):
37 | """should unload the dataset."""
38 | conn = self.conn
39 | teardown_db(conn)
40 | conn.close()
41 | conf.reset_heavy_dsn()
42 |
43 | class SQLObjectCategoryTest(SQLObjectFixtureTest):
44 | def assert_data_loaded(self, dataset):
45 | """assert that the dataset was loaded."""
46 | eq_(Category.get( dataset.gray_stuff.id).name,
47 | dataset.gray_stuff.name)
48 | eq_(Category.get( dataset.yellow_stuff.id).name,
49 | dataset.yellow_stuff.name)
50 |
51 | def assert_data_torndown(self):
52 | """assert that the dataset was torn down."""
53 | eq_(Category.select().count(), 0)
54 |
55 | class TestSQLObjectCategory(
56 | HavingCategoryData, SQLObjectCategoryTest, LoadableTest):
57 | pass
58 |
59 | class HavingCategoryDataStorable:
60 | """mixin that adds data to a LoadableTest."""
61 | def datasets(self):
62 | class WhateverIWantToCallIt(DataSet):
63 | class Meta:
64 | storable = Category
65 | class gray_stuff:
66 | id=1
67 | name='gray'
68 | class yellow_stuff:
69 | id=2
70 | name='yellow'
71 | return [WhateverIWantToCallIt]
72 |
73 | class TestSQLObjectCategoryStorable(
74 | HavingCategoryDataStorable, SQLObjectCategoryTest, LoadableTest):
75 | pass
76 | class TestSQLObjectCategoryAsDataType(
77 | HavingCategoryAsDataType, SQLObjectCategoryTest, LoadableTest):
78 | pass
79 |
80 | class TestSQLObjectPartialLoad(
81 | SQLObjectFixtureTest, LoaderPartialRecoveryTest):
82 | def assert_partial_load_aborted(self):
83 | raise SkipTest("I don't think sqlobject can support this feature")
84 |
85 | # t = self.conn.transaction()
86 | # eq_(Category.select(connection=t).count(), 0)
87 |
88 | class SQLObjectFixtureCascadeTest(SQLObjectFixtureTest):
89 | def assert_data_loaded(self, dataset):
90 | """assert that the dataset was loaded."""
91 | eq_(Offer.get(dataset.free_truck.id).name, dataset.free_truck.name)
92 |
93 | eq_(Product.get(
94 | dataset.truck.id).name,
95 | dataset.truck.name)
96 |
97 | eq_(Category.get(
98 | dataset.cars.id).name,
99 | dataset.cars.name)
100 | eq_(Category.get(
101 | dataset.free_stuff.id).name,
102 | dataset.free_stuff.name)
103 |
104 | def assert_data_torndown(self):
105 | """assert that the dataset was torn down."""
106 | eq_(Category.select().count(), 0)
107 | eq_(Offer.select().count(), 0)
108 | eq_(Product.select().count(), 0)
109 |
110 | class SQLObjectFixtureCascadeTestWithHeavyDB(SQLObjectFixtureCascadeTest):
111 | def setUp(self):
112 | if not conf.HEAVY_DSN:
113 | raise SkipTest
114 |
115 | SQLObjectFixtureCascadeTest.setUp(self, dsn=conf.HEAVY_DSN)
116 |
117 | class TestSQLObjectFixtureCascade(
118 | HavingOfferProductData, SQLObjectFixtureCascadeTest,
119 | LoadableTest):
120 | pass
121 | class TestSQLObjectFixtureCascadeWithHeavyDB(
122 | HavingOfferProductData, SQLObjectFixtureCascadeTestWithHeavyDB,
123 | LoadableTest):
124 | pass
125 | class TestSQLObjectFixtureCascadeAsType(
126 | HavingOfferProductAsDataType, SQLObjectFixtureCascadeTest,
127 | LoadableTest):
128 | pass
129 | class TestSQLObjectFixtureCascadeAsRef(
130 | HavingReferencedOfferProduct, SQLObjectFixtureCascadeTest,
131 | LoadableTest):
132 | pass
133 | class TestSQLObjectFixtureCascadeAsRefInherit(
134 | HavingRefInheritedOfferProduct, SQLObjectFixtureCascadeTest,
135 | LoadableTest):
136 | pass
137 | class TestSQLObjectFixtureCascadeAsRefInheritWithHeavyDB(
138 | HavingRefInheritedOfferProduct, SQLObjectFixtureCascadeTestWithHeavyDB,
139 | LoadableTest):
140 | pass
141 |
--------------------------------------------------------------------------------
Comments
45 | {% for comment in comment_list %} 46 | {% if comment.is_public %} 47 |49 | {{ forloop.counter }} 50 | {% if comment.user_url %}{{ comment.user_name }}{% else %}{{ comment.user_name }}{% endif %} says... 51 |
52 | {{ comment.comment|urlizetrunc:"60"|markdown:"safe" }} 53 |Posted at {{ comment.submit_date|date:"P" }} on {{ comment.submit_date|date:"F j, Y" }}
54 |