[Checkins] SVN: five.grok/trunk/ First functional test.

Lennart Regebro regebro at gmail.com
Thu Jul 17 15:44:23 EDT 2008


Log message for revision 88464:
  First functional test.
  

Changed:
  U   five.grok/trunk/buildout.cfg
  U   five.grok/trunk/src/five/grok/__init__.py
  U   five.grok/trunk/src/five/grok/components.py
  A   five.grok/trunk/src/five/grok/ftesting.zcml
  A   five.grok/trunk/src/five/grok/ftests/
  A   five.grok/trunk/src/five/grok/ftests/__init__.py
  A   five.grok/trunk/src/five/grok/ftests/test_grok_functional.py
  A   five.grok/trunk/src/five/grok/ftests/view/
  A   five.grok/trunk/src/five/grok/ftests/view/__init__.py
  A   five.grok/trunk/src/five/grok/ftests/view/argument.py
  A   five.grok/trunk/src/five/grok/ftests/view/test.pt
  U   five.grok/trunk/src/five/grok/testing.py
  U   five.grok/trunk/src/five/grok/tests/view/inline.py
  U   five.grok/trunk/src/five/grok/tests/view/twoviewsusetemplate.py
  U   five.grok/trunk/src/five/grok/tests/view/view.py

-=-
Modified: five.grok/trunk/buildout.cfg
===================================================================
--- five.grok/trunk/buildout.cfg	2008-07-17 19:33:35 UTC (rev 88463)
+++ five.grok/trunk/buildout.cfg	2008-07-17 19:44:22 UTC (rev 88464)
@@ -60,5 +60,5 @@
 [test]
 recipe = zc.recipe.testrunner
 eggs = five.grok
-eggs = ${instance:eggs}
 extra-paths = ${zope2:location}/lib/python
+defaults = ['--tests-pattern', '^f?tests$', '-v']

Modified: five.grok/trunk/src/five/grok/__init__.py
===================================================================
--- five.grok/trunk/src/five/grok/__init__.py	2008-07-17 19:33:35 UTC (rev 88463)
+++ five.grok/trunk/src/five/grok/__init__.py	2008-07-17 19:44:22 UTC (rev 88464)
@@ -7,7 +7,7 @@
 from grokcore.component.directive import context, name, provides
 from grokcore.component.decorators import subscribe
 
-from five.grok.components import View, Model, PageTemplate
+from five.grok.components import View, Model, PageTemplate, IGrokLayer, Skin
 from five.grok.directive import require, layer, template, templatedir
 
 # I don't know why this is necessary:

Modified: five.grok/trunk/src/five/grok/components.py
===================================================================
--- five.grok/trunk/src/five/grok/components.py	2008-07-17 19:33:35 UTC (rev 88463)
+++ five.grok/trunk/src/five/grok/components.py	2008-07-17 19:44:22 UTC (rev 88464)
@@ -6,6 +6,7 @@
 from zope.annotation.interfaces import IAttributeAnnotatable
 from zope.app.pagetemplate.engine import TrustedAppPT
 from zope.pagetemplate import pagetemplate, pagetemplatefile
+
 from zope.publisher.publish import mapply
 
 import Acquisition
@@ -20,7 +21,7 @@
     """Browser page with implicit Acquisition."""
 
 # XXX Should probably be a SimpleItem.
-class Model(Contained, persistent.Persistent):
+class Model(SimpleItem):
     # XXX Inheritance order is important here. If we reverse this,
     # then containers can't be models anymore because no unambigous MRO
     # can be established.
@@ -224,3 +225,9 @@
         template = self._template
         namespace.update(template.pt_getContext())
         return template.pt_render(namespace)
+    
+class IGrokLayer(interface.Interface):
+    pass
+
+class Skin(object):
+    pass

Added: five.grok/trunk/src/five/grok/ftesting.zcml
===================================================================
--- five.grok/trunk/src/five/grok/ftesting.zcml	                        (rev 0)
+++ five.grok/trunk/src/five/grok/ftesting.zcml	2008-07-17 19:44:22 UTC (rev 88464)
@@ -0,0 +1,12 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:grok="http://namespaces.zope.org/grok">
+
+  <!-- This file acts kinda like a virtual "site.zcml" during ftesting.
+   five.grok's zcml needs to be included. /-->
+  <include package="five.grok" file="meta.zcml" />
+  <include package="five.grok" />
+
+  <!-- And also grok all the ftests /-->
+  <grok:grok package="five.grok.ftests" />
+</configure>


Property changes on: five.grok/trunk/src/five/grok/ftesting.zcml
___________________________________________________________________
Name: svn:keywords
   + Id

Added: five.grok/trunk/src/five/grok/ftests/__init__.py
===================================================================


Property changes on: five.grok/trunk/src/five/grok/ftests/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: five.grok/trunk/src/five/grok/ftests/test_grok_functional.py
===================================================================
--- five.grok/trunk/src/five/grok/ftests/test_grok_functional.py	                        (rev 0)
+++ five.grok/trunk/src/five/grok/ftests/test_grok_functional.py	2008-07-17 19:44:22 UTC (rev 88464)
@@ -0,0 +1,67 @@
+import re
+import unittest
+from five import grok
+import os.path
+
+from pkg_resources import resource_listdir
+from zope.testing import doctest, renormalizing
+from zope.app.testing.functional import HTTPCaller
+from five.grok.testing import GrokFunctionalLayer
+from Testing.ZopeTestCase.zopedoctest.functional import getRootFolder, sync
+from Testing.ZopeTestCase import FunctionalDocTestSuite
+
+from Testing.ZopeTestCase import installProduct
+installProduct('PageTemplates')
+
+def http_call(method, path, data=None, **kw):
+    """Function to help make RESTful calls.
+
+    method - HTTP method to use
+    path - testbrowser style path
+    data - (body) data to submit
+    kw - any request parameters
+    """
+    
+    if path.startswith('http://localhost'):
+        path = path[len('http://localhost'):]
+    request_string = '%s %s HTTP/1.1\n' % (method, path)
+    for key, value in kw.items():
+        request_string += '%s: %s\n' % (key, value)
+    if data is not None:
+        request_string += '\r\n'
+        request_string += data
+    return HTTPCaller()(request_string, handle_errors=False)
+
+def suiteFromPackage(name):
+    files = resource_listdir(__name__, name)
+    suite = unittest.TestSuite()
+    for filename in files:
+        if not filename.endswith('.py'):
+            continue
+        if filename == '__init__.py':
+            continue
+
+        dottedname = 'five.grok.ftests.%s.%s' % (name, filename[:-3])
+        test = FunctionalDocTestSuite(
+            dottedname,
+            extraglobs=dict(http=HTTPCaller(),
+                            http_call=http_call,
+                            getRootFolder=getRootFolder,
+                            sync=sync),
+            optionflags=(doctest.ELLIPSIS+
+                         doctest.NORMALIZE_WHITESPACE+
+                         doctest.REPORT_NDIFF)
+            )
+        test.layer = GrokFunctionalLayer
+
+        suite.addTest(test)
+    return suite
+
+def test_suite():
+    suite = unittest.TestSuite()
+    for name in ['view',]:
+        suite.addTest(suiteFromPackage(name))
+    return suite
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: five.grok/trunk/src/five/grok/ftests/test_grok_functional.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: five.grok/trunk/src/five/grok/ftests/view/__init__.py
===================================================================
--- five.grok/trunk/src/five/grok/ftests/view/__init__.py	                        (rev 0)
+++ five.grok/trunk/src/five/grok/ftests/view/__init__.py	2008-07-17 19:44:22 UTC (rev 88464)
@@ -0,0 +1 @@
+# this is a package


Property changes on: five.grok/trunk/src/five/grok/ftests/view/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: five.grok/trunk/src/five/grok/ftests/view/argument.py
===================================================================
--- five.grok/trunk/src/five/grok/ftests/view/argument.py	                        (rev 0)
+++ five.grok/trunk/src/five/grok/ftests/view/argument.py	2008-07-17 19:44:22 UTC (rev 88464)
@@ -0,0 +1,71 @@
+"""
+
+  >>> from five.grok.ftests.view.argument import *
+  >>> id = getRootFolder()._setObject("manfred", Mammoth(id='manfred'))
+
+  >>> from Products.Five.testbrowser import Browser
+  >>> browser = Browser()
+  >>> browser.handleErrors = False
+
+Form variables such as GET parameters are dispatched to arguments of
+the render() method, should the method choose to take them:
+
+  >>> browser.open("http://localhost/manfred/render?message=Foo&another=Bar")
+  >>> print browser.contents
+  Message: Foo
+  Another: Bar
+
+Supplying more arguments than those specified has no effect:
+
+  >>> browser.open("http://localhost/manfred/render?message=There&another=Is&last=More")
+  >>> print browser.contents
+  Message: There
+  Another: Is
+
+If you don't supply all of the arguments, there will be a System Error:
+
+  >>> browser.open("http://localhost/manfred/render?message=Foo")
+  Traceback (most recent call last):
+  ...
+  TypeError: Missing argument to render(): another
+
+The same works with views that define update():
+
+  >>> browser.open("http://localhost/manfred/update?message=Foo&another=Bar")
+  >>> print browser.contents
+  Coming to us from update():
+  Message: Foo
+  Another: Bar
+
+  >>> browser.open("http://localhost/manfred/update?message=There&another=Is&last=More")
+  >>> print browser.contents
+  Coming to us from update():
+  Message: There
+  Another: Is
+
+  >>> browser.open("http://localhost/manfred/update?another=Bar")
+  Traceback (most recent call last):
+  ...
+  TypeError: Missing argument to update(): message
+
+"""
+from five import grok
+
+class Mammoth(grok.Model):
+    pass
+
+class RenderWithArguments(grok.View):
+    grok.name('render')
+
+    def render(self, message, another):
+        return "Message: %s\nAnother: %s" % (message, another)
+
+class UpdateWithArguments(grok.View):
+    grok.name('update')
+    grok.template('update')
+
+    def update(self, message, another):
+        self.message = message
+        self.another = another
+
+update = grok.PageTemplate(filename="test.pt")


Property changes on: five.grok/trunk/src/five/grok/ftests/view/argument.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: five.grok/trunk/src/five/grok/ftests/view/test.pt
===================================================================
--- five.grok/trunk/src/five/grok/ftests/view/test.pt	                        (rev 0)
+++ five.grok/trunk/src/five/grok/ftests/view/test.pt	2008-07-17 19:44:22 UTC (rev 88464)
@@ -0,0 +1,3 @@
+Coming to us from update():
+Message: <span tal:replace="view/message" />
+Another: <span tal:replace="view/another" />


Property changes on: five.grok/trunk/src/five/grok/ftests/view/test.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: five.grok/trunk/src/five/grok/testing.py
===================================================================
--- five.grok/trunk/src/five/grok/testing.py	2008-07-17 19:33:35 UTC (rev 88463)
+++ five.grok/trunk/src/five/grok/testing.py	2008-07-17 19:44:22 UTC (rev 88464)
@@ -76,3 +76,45 @@
         message,
         line.strip(),
         )
+
+
+from zope.app.testing.placelesssetup import tearDown as _cleanUp
+def cleanUp():
+    '''Cleans up the component architecture.'''
+    _cleanUp()
+    import Products.Five.zcml as zcml
+    zcml._initialized = 0
+
+def setDebugMode(mode):
+    '''Allows manual setting of Five's inspection of debug mode
+       to allow for ZCML to fail meaningfully.
+    '''
+    import Products.Five.fiveconfigure as fc
+    fc.debug_mode = mode
+
+import five.grok
+def safe_load_site():
+    '''Loads entire component architecture (w/ debug mode on).'''
+    cleanUp()
+    setDebugMode(1)
+    import Products.Five.zcml as zcml
+    zcml.load_site()
+    zcml.load_config('ftesting.zcml', five.grok)
+    setDebugMode(0)
+
+class Layer:
+
+    def setUp(cls):
+        '''Sets up the CA by loading etc/site.zcml.'''
+        safe_load_site()
+    setUp = classmethod(setUp)
+
+    def tearDown(cls):
+        '''Cleans up the CA.'''
+        cleanUp()
+    tearDown = classmethod(tearDown)
+
+GrokFunctionalLayer = Layer
+
+
+ 
\ No newline at end of file

Modified: five.grok/trunk/src/five/grok/tests/view/inline.py
===================================================================
--- five.grok/trunk/src/five/grok/tests/view/inline.py	2008-07-17 19:33:35 UTC (rev 88463)
+++ five.grok/trunk/src/five/grok/tests/view/inline.py	2008-07-17 19:44:22 UTC (rev 88464)
@@ -16,7 +16,7 @@
   <ul>
     <li><zope.publisher.browser.TestRequest instance URL=http://127.0.0.1></li>
     <li><five.grok.tests.view.inline.CavePainting object at 0x...></li>
-    <li><five.grok.tests.view.inline.Mammoth object at 0x...></li>
+    <li><...Mammoth...></li>
     <li><zope.app.pagetemplate.engine.TraversableModuleImporter object at 0x...></li>
   </ul>
   </body>

Modified: five.grok/trunk/src/five/grok/tests/view/twoviewsusetemplate.py
===================================================================
--- five.grok/trunk/src/five/grok/tests/view/twoviewsusetemplate.py	2008-07-17 19:33:35 UTC (rev 88463)
+++ five.grok/trunk/src/five/grok/tests/view/twoviewsusetemplate.py	2008-07-17 19:44:22 UTC (rev 88464)
@@ -33,7 +33,7 @@
   Traceback (most recent call last):
     ...
   ComponentLookupError:
-  ((<five.grok.tests.view.twoviewsusetemplate.Mammoth object at 0x...>,
+  ((<...Mammoth...>,
   <zope.publisher.browser.TestRequest instance URL=http://127.0.0.1>),
   <InterfaceClass zope.interface.Interface>, 'templ')
 

Modified: five.grok/trunk/src/five/grok/tests/view/view.py
===================================================================
--- five.grok/trunk/src/five/grok/tests/view/view.py	2008-07-17 19:33:35 UTC (rev 88463)
+++ five.grok/trunk/src/five/grok/tests/view/view.py	2008-07-17 19:44:22 UTC (rev 88464)
@@ -11,8 +11,8 @@
   >>> view = component.getMultiAdapter((manfred, request), name='cavepainting')
   >>> view()
   'A cave painting of a mammoth'
-
-  >>> view.context is manfred
+  
+  >>> view.context.aq_base is manfred
   True
   >>> view.request is request
   True
@@ -28,7 +28,7 @@
   >>> view = component.getMultiAdapter((manfred, request), name='food')
   Traceback (most recent call last):
     ...
-  ComponentLookupError: ((<five.grok.tests.view.view.Mammoth object at 0x...>, <zope.publisher.browser.TestRequest instance URL=http://127.0.0.1>), <InterfaceClass zope.interface.Interface>, 'food')
+  ComponentLookupError: ((<...Mammoth...>, <zope.publisher.browser.TestRequest instance URL=http://127.0.0.1>), <InterfaceClass zope.interface.Interface>, 'food')
 
 """
 



More information about the Checkins mailing list