📜 ⬆️ ⬇️

Manual: Pyramid for People - Part 4

Part 3: unit and functional testing, Hello World at Chameleon

Step 04: View Framework

Enough with us “hello world”, now get down to work on the Projector. A UX person usually has a number of views that need to be prototyped and mapped to a URL structure.

We want to make this process fast and productive.
')
In this step, we copy the structure of the site map like this:
/
/about.html
/acme
/people
/
/about.html
/acme
/people
... and make a series of URLs that accomplish this. Along the way, we create more views and more templates.

Goals
What's expected
Steps

$ cd ../../creatingux; mkdir step04; cd step04

(Unchanged) Copy one to the other - step04/application.py :
from wsgiref.simple_server import make_server

from pyramid.config import Configurator

def main ():
config = Configurator ()
config . scan ( "views" )
app = config . make_wsgi_app ()
return app

if __name__ == '__main__' :
app = main ()
server = make_server ( '0.0.0.0' , 8080 , app)
server . serve_forever ()
Further also here - step04/views.py :
from pyramid.view import view_config

@view_config (renderer = "index.pt" )
def index_view (request):
return {}

@view_config (renderer = "about.pt" , name = "about.html" )
def about_view (request):
return {}

@view_config (renderer = "company.pt" , name = "acme" )
def company_view (request):
return { "company" : COMPANY, "projects" : PROJECTS}

@view_config (renderer = "people.pt" , name = "people" )
def people_view (request):
return { "company" : COMPANY, "people" : PEOPLE}

# Dummy data
COMPANY = "ACME, Inc."

PEOPLE = [
{ 'name' : 'sstanton' , 'title' : 'Susan Stanton' },
{ 'name' : 'bbarker' , 'title' : 'Bob Barker' },
]

PROJECTS = [
{ 'name' : 'sillyslogans' , 'title' : 'Silly Slogans' },
{ 'name' : 'meaningless permissions' , 'title' : 'Meaningless Missions' },
]
And here - step04/index.pt :
<html>
<head>
<title> Projector - Home </ title>
</ head>
<body>
<ul>
<li> <a href= "/"> Home </a> </ li>
<li> <a href= "/about.html"> About Projector </a> </ li>
<li> <a href= "/acme"> ACME, Inc. </a> </ li>
<li> <a href= "/people"> People </a> </ li>
</ ul>
<h1> Projector - Home </ h1>
</ body>
</ html>
Further here - step04/about.pt :
<html>
<head>
<title> Projector - About </ title>
</ head>
<body>
<ul>
<li> <a href= "/"> Home </a> </ li>
<li> <a href= "/about.html"> About Projector </a> </ li>
<li> <a href= "/acme"> ACME, Inc. </a> </ li>
<li> <a href= "/people"> People </a> </ li>
</ ul>
<h1> Projector - About </ h1>
<p> Projector is a simple project management tool capable of hosting.
multiple projects for multiple independent companies
sharing a developer pool between autonomous companies. </ p>
</ body>
</ html>
Here is step04/company.pt :
<html>
<head>
<title> Projector - People </ title>
</ head>
<body>
<ul>
<li> <a href= "/"> Home </a> </ li>
<li> <a href= "/about.html"> About Projector </a> </ li>
<li> <a href= "/acme"> ACME Inc. </a> </ li>
<li> <a href= "/people"> People </a> </ li>
</ ul>
<h1> People </ h1>
<ul>
<li tal: repeat = "person people" >
<a href= "$$person.name}"> $ {person.title} </a>
</ li>
</ ul>
</ body>
</ html>
And finally, here is step04/tests.py :
import unittest

class ProjectorViewsUnitTests (unittest . TestCase):
def test_hello_view ( self ):
from views import index_view
result = index_view ({})
self . assertEqual ( len (result . keys ()), 0 )

def test_about_view ( self ):
from views import about_view
result = about_view ({})
self . assertEqual ( len (result . keys ()), 0 )

def test_company_view ( self ):
from views import company_view
result = company_view ({})
self . assertEqual (result [ "company" ], "ACME, Inc." )
self . assertEqual ( len (result [ "projects" ]), 2 )

def test_people_view ( self ):
from views import people_view
result = people_view ({})
self . assertEqual (result [ "company" ], "ACME, Inc." )
self . assertEqual ( len (result [ "people" ]), 2 )

class ProjectorFunctionalTests (unittest . TestCase):
def setUp ( self ):
from application import main
app = main ()
from webtest import TestApp
self . testapp = TestApp (app)

def test_home ( self ):
res = self . testapp . get ( '/' , status = 200 )
self . failUnless ( 'Home' in res . body)

def test_it ( self ):
res = self . testapp . get ( '/' , status = 200 )
self . failUnless ( 'Home' in res . body)
res = self . testapp . get ( '/about.html' , status = 200 )
self . failUnless ( 'autonomous' in res . body)
res = self . testapp . get ( '/ people' , status = 200 )
self . failUnless ( 'Susan' in res . body)
res = self . testapp . get ( '/ acme' , status = 200 )
self . failUnless ( 'Silly Slogans' in res . body)
Further we write:
$ nosetests
That should give us a report on 6 tests.
Run the application:
$ python application.py
And we rejoice in the result in the browser - 127.0.0.1:8080

Additional questions

What happens if you have two view registrations with no @ name attribute, meaning both as the default?
Is it true that Chameleon (now, if we are talking about the second version) is anyway better to provide you with error messages? Try this out by putting a few bugs in your Python expressions.
Will WebTest work correctly for these errors?
Does adding .html, to your URLs, influence anything?

Analysis

We began the process of building a URL space that maps to objects and hierarchy in our application. At the moment, we have modeled this using views.

Despite the increase in the number of our tests, each of them is still very small. Even such a simple test will still catch most of the silly mistakes that come up during the initial development process. We hope you find the nosetests for yourself more productive than a simple click.

Theses

How do the registrations happen under the hood?
Chameleon, caching, and putting finished versions to disk

Step 05: Creating the main template

Source: https://habr.com/ru/post/136251/


All Articles