RESTful doctesting using app.request

!/usr/bin/env python

  1. """
  2. RESTful web.py testing
  3. usage: python webapp.py 8080 [--test]
  4. >>> req = app.request('/mathematicians', method='POST')
  5. >>> req.status
  6. '400 Bad Request'
  7. >>> name = {'first': 'Beno\xc3\xaet', 'last': 'Mandelbrot'}
  8. >>> data = urllib.urlencode(name)
  9. >>> req = app.request('/mathematicians', method='POST', data=data)
  10. >>> req.status
  11. '201 Created'
  12. >>> created_path = req.headers['Location']
  13. >>> created_path
  14. '/mathematicians/b-mandelbrot'
  15. >>> fn = '<h1 class=fn>{0} {1}</h1>'.format(name['first'], name['last'])
  16. >>> assert fn in app.request(created_path).data
  17. """
  18. import doctest
  19. import urllib
  20. import sys
  21. import web
  22. paths = (
  23. '/mathematicians(/)?', 'Mathematicians',
  24. '/mathematicians/([a-z])-([a-z]{2,})', 'Mathematician'
  25. )
  26. app = web.application(paths, globals())
  27. dbname = {True: 'test', False: 'production'}[sys.argv[-1] == '--test']
  28. db = {} # db = web.database(..., db='math_{0}'.format(dbname))
  29. class Mathematicians:
  30. def GET(self, slash=False):
  31. """list all mathematicians and form to create new one"""
  32. if slash:
  33. raise web.seeother('/mathematicians')
  34. mathematicians = db.items() # db.select(...)
  35. return web.template.Template("""$def with (mathematicians)
  36. <!doctype html>
  37. <html>
  38. <head>
  39. <meta charset=utf-8>
  40. <title>Mathematicians</title>
  41. </head>
  42. <body>
  43. <h1>Mathematicians</h1>
  44. $if mathematicians:
  45. <ul class=blogroll>
  46. $for path, name in mathematicians:
  47. <li class=vcard><a class="fn url"
  48. href=/mathematicians/$path>$name.first $name.last</a></li>
  49. </ul>
  50. <form action=/mathematicians method=post>
  51. <label>First <input name=first type=text></label>
  52. <label>Last <input name=last type=text></label>
  53. <input type=submit value=Add>
  54. </form>
  55. </body>
  56. </html>""")(mathematicians)
  57. def POST(self, _):
  58. """create new mathematician"""
  59. name = web.input('first', 'last')
  60. key = '{0}-{1}'.format(name.first[0].lower(), name.last.lower())
  61. name.first, name.last = name.first.capitalize(), name.last.capitalize()
  62. db[key] = name # db.insert(...)
  63. path = '/mathematicians/{0}'.format(key)
  64. web.ctx.status = '201 Created'
  65. web.header('Location', path)
  66. return web.template.Template("""$def with (path, name)
  67. <!doctype html>
  68. <html>
  69. <head>
  70. <meta charset=utf-8>
  71. <title>Profile Created</title>
  72. </head>
  73. <body>
  74. <p>Profile created for <a href=$path>$name.first $name.last</a>.</p>
  75. </body>
  76. </html>""")(path, name)
  77. class Mathematician:
  78. def GET(self, first_initial, last_name):
  79. """display mathematician"""
  80. key = '{0}-{1}'.format(first_initial, last_name)
  81. try:
  82. mathematician = db[key] # db.select(...)
  83. except KeyError:
  84. raise web.notfound()
  85. return web.template.Template("""$def with (name)
  86. <!doctype html>
  87. <html>
  88. <head>
  89. <meta charset=utf-8>
  90. <title>$name.first $name.last</title>
  91. </head>
  92. <body class=vcard>
  93. <p><a href=/mathematicians rel=up>Mathematicians</a> &#x25B8;</p>
  94. <h1 class=fn>$name.first $name.last</h1>
  95. </body>
  96. </html>""")(mathematician)
  97. if __name__ == "__main__":
  98. if sys.argv[-1] == '--test':
  99. doctest.testmod()
  100. else:
  101. app.run()