diff options
| author | ianb <devnull@localhost> | 2005-05-15 23:02:33 +0000 |
|---|---|---|
| committer | ianb <devnull@localhost> | 2005-05-15 23:02:33 +0000 |
| commit | 88a297c92ea8275f89367362c21d1283389c8325 (patch) | |
| tree | 544af78699bef53568d144a449a323068bed237f /docs | |
| parent | 949d832efdac9b2c882c5ba2961ad7b4a5abdcb9 (diff) | |
| download | paste-88a297c92ea8275f89367362c21d1283389c8325.tar.gz | |
Further work on the tutorial
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/blog-tutorial.txt | 196 |
1 files changed, 174 insertions, 22 deletions
diff --git a/docs/blog-tutorial.txt b/docs/blog-tutorial.txt index fdc0762..6a23f30 100644 --- a/docs/blog-tutorial.txt +++ b/docs/blog-tutorial.txt @@ -52,17 +52,17 @@ Setting Up The App .. comment: >>> from paste.tests.doctest_webapp import * - >>> BASE = '/var/www/example-builds/wkblog' + >>> BASE = '/var/www/example-builds/wwblog' >>> import sys >>> clear_dir(BASE) - >>> run("app-setup create --template=webkit_zpt %s" % BASE) + >>> run("paste-setup create --template=webkit_zpt %s" % BASE) >>> os.chdir(BASE) :: $ export PYTHONPATH=/path/to/Paste:$PYTHONPATH - $ BASE=/var/www/example-builds/wkblog - $ app-setup create --template=webkit_zpt $BASE + $ BASE=/var/www/example-builds/wwblog + $ paste-setup create --template=webkit_zpt $BASE $ cd $BASE The Model @@ -81,12 +81,6 @@ Here's the model: create_file('db.py', 'v1', r""" from sqlobject import * - try: - from datetime import datetime - now = datetime.now - except ImportError: - from mx import DateTime - now = DateTime.now class Article(SQLObject): url = StringCol(notNull=True) @@ -95,7 +89,7 @@ Here's the model: content_mime_type = StringCol(notNull=True) author = ForeignKey('User') parent = ForeignKey('Article', default=None) - created = DateTimeCol(notNull=True, default=now) + created = DateTimeCol(notNull=True, default=DateTimeCol.now) last_updated = DateTimeCol(default=None) atom_id = StringCol() hidden = BoolCol(notNull=True, default=False) @@ -112,23 +106,16 @@ Here's the model: username = StringCol(alternateID=True) email = StringCol() name = StringCol() + homepage = StringCol() password_encoded = StringCol() role = StringCol(notNull=True, default='user') """) .. raw:: html - :file: resources/BlogTutorial/db.py.v1.gen.html + :file: resources/blog-tutorial/db.py.v1.gen.html A few things to note: -* Sadly, both datetime_ and mxDateTime_ are pseudo-standards. Well, - datetime is the standard, but mxDateTime has the legacy. So we have - to do this little dance to import one or the other. (We use ``now`` - later as a default) - -.. _datetime: http://python.org/doc/current/lib/module-datetime.html -.. _mxDateTime: http://www.egenix.com/files/python/mxDateTime.html - * All the columns allow ``NULL`` by default, unless we say ``notNull=True``. @@ -163,7 +150,7 @@ These classes have lots of other *behavior*, but this should be a good list of actual information. We'll add more behavior later. Now we'll create the database. First we configure it, adding these -lines:: +lines to ``server.conf``:: import os database = 'sqlite:%s/data.db' % os.path.dirname(__file__) @@ -184,4 +171,169 @@ Now we'll use ``sqlobject-admin`` to set up the tables: .. comment (do it) - >>> run('sqlobject-admin create -f server.conf -m wkblog.db') + >>> run_command('sqlobject-admin create -f server.conf ' + ... '-m wwblog.db', 'create', and_print=True) + + +.. raw:: html + :file: resources/blog-tutorial/shell-command.create.gen.html + +Fixture Data +------------ + +To test things later we'll need a bit of data to make the tests +interesting. It's best if we write code to clear any data and put +known data in -- that way we can restore the database at any time to a +known state, and can write our tests against that data. + +We'll add some code to the end of ``db.py``: + +.. comment (change) + + >>> append_to_file('db.py', 'append-fixture', r""" + ... + ... from paste import CONFIG + ... def reset_data(): + ... sqlhub.processConnection = connectionForURI(CONFIG['database']) + ... for soClass in (User, Category, Article): + ... soClass.clearTable() + ... auth = User(username='author', email='author@example.com', + ... name='Author Person', password_encoded=None, + ... role='author', homepage=None) + ... user = User(username='commentor', email='comment@example.com', + ... name='Comment Person', password_encoded=None, + ... role='user', homepage='http://yahoo.com') + ... programming = Category(name='Programming') + ... family = Category(name='family') + ... a1 = Article(url='/2004/05/01/article1.html', + ... title='First article', + ... content='This is an article', + ... content_mime_type='text/html', + ... author=auth, parent=None, + ... last_updated=None, atom_id=None) + ... a2 = Article(url='/2004/05/10/article2.html', + ... title='Second article', + ... content='Another\narticle', + ... content_mime_type='text/plain', + ... author=auth, parent=None, + ... last_updated=None, atom_id=None) + ... c1 = Article(url='/2004/05/01/article1-comment1.html', + ... title=None, content='Nice article!', + ... content_mime_type='text/x-untrusted-html', + ... author=user, parent=a1, last_updated=None, + ... atom_id=None, article_type='comment') + ... a1.addCategory(programming) + ... a1.addCategory(family) + ... """) + +.. raw:: html + :file: resources/blog-tutorial/db.py.append-fixture.gen.html + +Test Fixture +------------ + +See `Testing Applications With Paste <testing-applications.html>`_ for +more on the details of how we set up testing. We'll be using `py.test +<http://codespeak.net/py/current/doc/test.html>`_ for the testing +framework. + +First, lets create our own test fixture. We'll create a directory +``tests/`` and add a file ``fixture.py``. + +.. comment (create files): + + >>> create_file('tests/__init__.py', 'v1', '#\n') + >>> create_file('tests/fixture.py', 'v1', r""" + ... from paste.tests.fixture import setup_module as paste_setup + ... from wwblog import db + ... + ... def setup_module(module): + ... paste_setup(module) + ... db.reset_data() + ... """) + +.. raw:: html + :file: resources/blog-tutorial/tests/fixture.py.v1.gen.html + +Now in each test we'll do:: + + from wwblog.tests.fixture import setup_module + +And that will give us a consistent state for the module (note that +data isn't reset between each test in the module, just once for the +module, so we'll have to be aware of that). + +Let's write a first test: + +.. comment (create test): + + >>> create_file('tests/test_db.py', 'v1', r""" + ... from fixture import setup_module + ... from wwblog.db import * + ... + ... def test_data(): + ... # make sure we have the two users we set up + ... assert len(list(User.select())) == 2 + ... # and get the first article for testing + ... a1 = list(Article.selectBy(title='First article'))[0] + ... # make sure it has categories, then make sure the + ... # categories contain this article as well + ... assert len(list(a1.categories)) == 2 + ... for cat in a1.categories: + ... assert a1 in cat.articles + ... """) + +.. raw:: html + :file: resources/blog-tutorial/tests/test_db.py.v1.gen.html + +For the most part, this stuff is already tested by SQLObject, but this +is a basic sanity check, and a test that we have set up the classes +properly. One problem, though, is that we have to make sure that +``sys.path`` is set up properly. We could set ``$PYTHONPATH``, but +that can be a bit annoying; we'll put it in a special file +``conftest.py`` that py.test loads up: + +.. comment (create): + + >>> create_file('conftest.py', 'v1', r""" + ... import sys, os + ... sys.path.append('/path/to/Paste') + ... sys.path.append(os.path.dirname(os.path.dirname(__file__))) + ... from paste.util.thirdparty import add_package + ... add_package('sqlobject') + ... """) + +.. raw:: html + :file: resources/blog-tutorial/conftest.py.v1.gen.html + +Now we should be able to run py.test: + +.. comment (do): + + >>> run_command('py.test', 't1', and_print=True) + inserting into sys.path: ... + =========================== test process starts =========================== + testing-mode: inprocess + executable: .../python (...) + using py lib: .../py <rev ...> + wwblog/tests/test_db.py[1] . + ================= tests finished: 1 passed in ... seconds ================= + +.. raw:: html + :file: resources/blog-tutorial/shell-command.t1.gen.html + +Very good! Alright then, on to making an application... + +The Front Page +-------------- + +First we'll set up a simple front page. We'll write a new +``index.py``: + +.. comment (do so): + + >>> create_file('web/index.py', 'v1', r""" + ... """) + +.. raw:: html + :file: resources/blog-tutorial/web/index.py.v1.gen.html |
