[Checkins] SVN: Sandbox/dirceu/megrok.form/src/megrok/form/ Adding some tests to megrok.form

Dirceu Pereira Tiegs dirceutiegs at gmail.com
Mon Feb 4 12:11:24 EST 2008


Log message for revision 83501:
  Adding some tests to megrok.form

Changed:
  U   Sandbox/dirceu/megrok.form/src/megrok/form/README.txt
  A   Sandbox/dirceu/megrok.form/src/megrok/form/TODO.txt
  D   Sandbox/dirceu/megrok.form/src/megrok/form/app.py
  A   Sandbox/dirceu/megrok.form/src/megrok/form/browser.py
  U   Sandbox/dirceu/megrok.form/src/megrok/form/configure.zcml
  A   Sandbox/dirceu/megrok.form/src/megrok/form/constraints.py
  U   Sandbox/dirceu/megrok.form/src/megrok/form/fields.py
  A   Sandbox/dirceu/megrok.form/src/megrok/form/ftesting.zcml
  U   Sandbox/dirceu/megrok.form/src/megrok/form/overrides.zcml
  D   Sandbox/dirceu/megrok.form/src/megrok/form/test_validators.py
  A   Sandbox/dirceu/megrok.form/src/megrok/form/tests/
  A   Sandbox/dirceu/megrok.form/src/megrok/form/tests/__init__.py
  A   Sandbox/dirceu/megrok.form/src/megrok/form/tests/test_constraints.py
  A   Sandbox/dirceu/megrok.form/src/megrok/form/tests/test_form.py
  D   Sandbox/dirceu/megrok.form/src/megrok/form/validators.py

-=-
Modified: Sandbox/dirceu/megrok.form/src/megrok/form/README.txt
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/README.txt	2008-02-04 16:56:33 UTC (rev 83500)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/README.txt	2008-02-04 17:11:23 UTC (rev 83501)
@@ -2,40 +2,70 @@
 megrok.form
 ===========
 
-:Author: Dirceu Pereira Tiegs
+megrok.form is a helper package that provides some useful fields, widgets and constraints for Grok.
 
-megrok.form is a helper package that provides some very useful fields, widgets and validation methods for Grok.
-
 Fields
 ------
 
-- Email, a TextLine field with a default validator (contraint);
-- HTML, a Text field that uses z3c.widget.tiny;
-- File, from collective.namedfile;
-- Image, from collective.namedfile;
+- Email, a TextLine field with a default contraint
+- HTML, a Text field that uses z3c.widget.tiny
+- File, from collective.namedfile
+- Image, from collective.namedfile
 
 Widgets
 -------
 
 megrok.form overrides the default widgets for:
 
-- zope.interface.schema.Date (using zc.datetimewidget.widget.DateWidget);
-- zope.interface.schema.Datetime (using zc.datetimewidget.widget.DatetimeWidget);
+- zope.interface.schema.Date (using zc.datetimewidget.widget.DateWidget)
+- zope.interface.schema.Datetime (using zc.datetimewidget.widget.DatetimeWidget)
 
+And add new widgets for Image and File (from collective.namedfile).
+
 Validators / Constraints
 ------------------------
 
-megrok.form add validators for:
+megrok.form add constraints for:
 
 - SSN
-- US Phone Numbers;
-- International Phone Numbers;
+- US Phone Numbers
+- International Phone Numbers
 - Zip Code
 - URL
 - Email
 
-TODO
-----
+Installation
+------------
 
-- Remove "app.py" and add some automated tests;
-- Release the egg on cheeseshop.
\ No newline at end of file
+To use megrok.form under Grok all you need is to install megrok.form as an egg 
+and include it's zcml. The best place to do this is to make megrok.form
+a dependency of your application by adding it to your install_requires
+list in setup.cfg. If you used grokprojet to create your application setup.cfg
+is located in the project root. It should look something like this::
+
+   install_requires=['setuptools',
+                     'grok',
+                     'megrok.form',
+                     # Add extra requirements here
+                     ],
+
+Then include megrok.form in your configure.zcml. If you used grokproject to
+create your application it's at src/<projectname>/configure.zcml. Add the
+include line after the include line for grok, but before the grokking of the
+current package. It should look something like this::
+
+      <include package="grok" />
+      <include package="megrok.form" />  
+      <grok:grok package="." />
+  
+Then run bin/buildout again. You should now see buildout saying something like::
+
+   Getting distribution for 'megrok.form'.
+   Got megrok.form 0.1.
+
+That's all.
+
+Authors
+-------
+
+- Dirceu Pereira Tiegs (dirceutiegs at gmail dot com)
\ No newline at end of file

Added: Sandbox/dirceu/megrok.form/src/megrok/form/TODO.txt
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/TODO.txt	                        (rev 0)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/TODO.txt	2008-02-04 17:11:23 UTC (rev 83501)
@@ -0,0 +1,15 @@
+================
+megrok.form TODO
+================
+
+- Release the egg on cheeseshop
+
+- Create a widget for zope.interface.schema.Time (based on z3c.widget.dropdowndatewidget)
+
+- Create / find a field for Reference (take a look at zc.relation, zc.relationship and lovely.relation)
+
+- Test z3c.autoinclude (https://svn.openplans.org/svn/snowsprint/z3c.autoinclude/)
+
+- Look at kupu/formlib integration (http://svn.plone.org/svn/plone/plone.app.form/branches/plip200-kupu-widget)
+
+- Look at KSS-based form validation (http://svn.plone.org/svn/plone/plone.app.form/branches/plip202-formlib-kss)
\ No newline at end of file

Deleted: Sandbox/dirceu/megrok.form/src/megrok/form/app.py
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/app.py	2008-02-04 16:56:33 UTC (rev 83500)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/app.py	2008-02-04 17:11:23 UTC (rev 83501)
@@ -1,44 +0,0 @@
-import grok
-from zope import interface, schema
-from megrok.form.fields import Email, Image, HTML, File
-
-class megrokform_test(grok.Application, grok.Container):
-    pass
-
-class IPerson(interface.Interface):
-    """ A simple class used to show how to use widgets and fields from megrok.form
-    """
-    name = schema.TextLine(title=u"Name")
-    email = Email(title=u"Email")
-    picture = Image(title=u"Picture")
-    description = HTML(title=u"Description")
-    birthday = schema.Date(title=u"Birthday")
-    resume = File(title=u"Resume")
-
-class Person(grok.Model):
-    interface.implements(IPerson)
-
-    def __init__(self, name, email, picture, description, birthday, resume):
-        self.name = name
-        self.email = email
-        self.picture = picture
-        self.description = description
-        self.birthday = birthday
-        self.resume = resume
-
-class AddPerson(grok.AddForm):
-    grok.context(megrokform_test)
-    form_fields = grok.AutoFields(Person)
-
-    @grok.action('Add person')
-    def add(self, **data):
-        obj = Person(**data)
-        name = data['name'].lower().replace(' ', '_')
-        self.context[name] = obj
-
-class Edit(grok.EditForm):
-    grok.context(Person)
-    form_fields = grok.AutoFields(Person)
-
-class Index(grok.DisplayForm):
-    grok.context(Person)

Added: Sandbox/dirceu/megrok.form/src/megrok/form/browser.py
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/browser.py	                        (rev 0)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/browser.py	2008-02-04 17:11:23 UTC (rev 83501)
@@ -0,0 +1,29 @@
+from zope.publisher.interfaces import NotFound
+import mimetypes
+import os.path
+from collective.namedfile.browser import UrlDispatcher
+
+class FileViewDispatcher(UrlDispatcher):
+    """See collective.namedfile.browser
+    """
+    
+    def __call__(self):    
+        if not self.traverse_subpath:
+            raise NotFound(self, '', self.request)
+        field_name = self.traverse_subpath[0]
+        form_field = self.context.form_fields.get(field_name, None)
+        if form_field is None:
+            raise NotFound(self, field_name, self.request)
+        field = form_field.field.bind(self.context.context)
+        file = field.get(self.context.context)
+        if getattr(file, 'filename', None):
+            extension = os.path.splitext(file.filename)[1].lower()
+            contenttype = mimetypes.types_map.get(extension,
+                                                  "application/octet-stream")
+        elif file.contentType:
+            contenttype = file.contentType
+        else:
+            contenttype = "application/octet-stream"
+        self.request.response.setHeader("Content-Type", contenttype)
+        self.request.response.setHeader("Content-Length", file.getSize())
+        return file.data


Property changes on: Sandbox/dirceu/megrok.form/src/megrok/form/browser.py
___________________________________________________________________
Name: svn:executable
   + *

Modified: Sandbox/dirceu/megrok.form/src/megrok/form/configure.zcml
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/configure.zcml	2008-02-04 16:56:33 UTC (rev 83500)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/configure.zcml	2008-02-04 17:11:23 UTC (rev 83501)
@@ -17,6 +17,5 @@
   <include file="overrides.zcml" />
 
   <include package="grok" />
-  <grok:grok package="." />
 
 </configure>

Copied: Sandbox/dirceu/megrok.form/src/megrok/form/constraints.py (from rev 83310, Sandbox/dirceu/megrok.form/src/megrok/form/validators.py)
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/constraints.py	                        (rev 0)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/constraints.py	2008-02-04 17:11:23 UTC (rev 83501)
@@ -0,0 +1,48 @@
+import re
+
+def validate_expression(value, expression, **kwargs):
+    ignore = kwargs.get('ignore', None)
+    if ignore:
+        if isinstance(ignore, basestring):
+            ignore = re.compile(ignore)
+        value = ignore.sub('', value)
+    if expression.match(value):
+        return True
+    return False
+    
+def isSSN(value, **kwargs):
+    expr = re.compile(r'^\d{9}$')
+    errmsg = 'is not a well formed SSN.'
+    return validate_expression(value, expr, errmsg=errmsg, **kwargs)
+
+def isUSPhoneNumber(value, **kwargs):
+    expr = re.compile(r'^\d{10}$')
+    if not kwargs.get('ignore', None):
+        kwargs['ignore'] = re.compile(r'[\(\)\-\s]')
+    errmsg = 'is not a valid us phone number.'
+    return validate_expression(value, expr, errmsg=errmsg, **kwargs)
+    
+def isInternationalPhoneNumber(value, **kwargs):
+    expr = re.compile(r'^\d+$')
+    if not kwargs.get('ignore', None):
+        kwargs['ignore'] = re.compile(r'[\(\)\-\s\+]')
+    errmsg = 'is not a valid international phone number.'
+    return validate_expression(value, expr, errmsg=errmsg, **kwargs)
+    
+def isZipCode(value, **kwargs):
+    expr = re.compile(r'^(\d{5}|\d{9})$')
+    errmsg = 'is not a valid zip code.'
+    return validate_expression(value, expr, errmsg=errmsg, **kwargs)
+    
+def isURL(value, **kwargs):
+    protocols = ('http', 'ftp', 'irc', 'news', 'imap', 'gopher', 'jabber',
+        'webdav', 'smb', 'fish', 'ldap', 'pop3', 'smtp', 'sftp', 'ssh'
+    )
+    expr = re.compile(r'(%s)s?://[^\s\r\n]+' % '|'.join(protocols))
+    errmsg = 'is not a valid url.'
+    return validate_expression(value, expr, errmsg=errmsg, **kwargs)
+    
+def isEmail(value, **kwargs):
+    expr = re.compile(r"^(\w&.%#$&'\*+-/=?^_`{}|~]+!)*[\w&.%#$&'\*+-/=?^_`{}|~]+@(([0-9a-z]([0-9a-z-]*[0-9a-z])?\.)+[a-z]{2,6}|([0-9]{1,3}\.){3}[0-9]{1,3})$", re.IGNORECASE)
+    errmsg = 'is not a valid email address.'
+    return validate_expression(value, expr, errmsg=errmsg, **kwargs)
\ No newline at end of file

Modified: Sandbox/dirceu/megrok.form/src/megrok/form/fields.py
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/fields.py	2008-02-04 16:56:33 UTC (rev 83500)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/fields.py	2008-02-04 17:11:23 UTC (rev 83501)
@@ -1,12 +1,12 @@
 from zope import interface, schema
 from collective.namedfile.field import NamedImage as Image
 from collective.namedfile.field import NamedFile as File
-import validators
+import constraints
 import interfaces
 
 class Email(schema.TextLine):
     def __init__(self, **kw):
-        kw['constraint'] = validators.isEmail
+        kw['constraint'] = constraints.isEmail
         super(Email, self).__init__(**kw)
 
 class HTML(schema.Text):

Added: Sandbox/dirceu/megrok.form/src/megrok/form/ftesting.zcml
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/ftesting.zcml	                        (rev 0)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/ftesting.zcml	2008-02-04 17:11:23 UTC (rev 83501)
@@ -0,0 +1,35 @@
+<configure
+   xmlns="http://namespaces.zope.org/zope"
+   i18n_domain="megrok.form.tests"
+   package="megrok.form.tests"
+   >
+
+  <include package="grok" />
+  <include package="megrok.form" />
+
+  <!-- Typical functional testing security setup -->
+  <securityPolicy
+      component="zope.app.securitypolicy.zopepolicy.ZopeSecurityPolicy"
+      />
+
+  <unauthenticatedPrincipal
+      id="zope.anybody"
+      title="Unauthenticated User"
+      />
+  <grant
+      permission="zope.View"
+      principal="zope.anybody"
+      />
+
+  <principal
+      id="zope.mgr"
+      title="Manager"
+      login="mgr"
+      password="mgrpw"
+      />
+
+  <role id="zope.Manager" title="Site Manager" />
+  <grantAll role="zope.Manager" />
+  <grant role="zope.Manager" principal="zope.mgr" />
+
+</configure>

Modified: Sandbox/dirceu/megrok.form/src/megrok/form/overrides.zcml
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/overrides.zcml	2008-02-04 16:56:33 UTC (rev 83500)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/overrides.zcml	2008-02-04 17:11:23 UTC (rev 83501)
@@ -12,7 +12,7 @@
   <browser:page
       for="grok.interfaces.IGrokForm"
       name="file"
-      class="collective.namedfile.browser.FileViewDispatcher"
+      class=".browser.FileViewDispatcher"
       permission="zope.Public"
       />
 

Deleted: Sandbox/dirceu/megrok.form/src/megrok/form/test_validators.py
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/test_validators.py	2008-02-04 16:56:33 UTC (rev 83500)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/test_validators.py	2008-02-04 17:11:23 UTC (rev 83501)
@@ -1,46 +0,0 @@
-import unittest
-import validators
-
-class TestValidation(unittest.TestCase):
-
-    def test_isSSN(self):
-        v = validators.isSSN
-        self.failUnlessEqual(v('111223333'), True)
-        self.failUnlessEqual(v('111-22-3333', ignore=r'-'), True)
-
-    def test_isUSPhoneNumber(self):
-        v = validators.isUSPhoneNumber
-        self.failUnlessEqual(v('(212) 555-1212',
-                               ignore=r'[\s\(\)\-]'), True)
-        self.failUnlessEqual(v('2125551212',
-                               ignore=r'[\s\(\)\-]'), True)
-
-        self.failUnlessEqual(v('(212) 555-1212'), True)
-        
-    def test_isInternationalPhoneNumber(self):
-        v = validators.isInternationalPhoneNumber
-        self.failUnlessEqual(v('+1 713 942 2377'), True)
-        self.failUnlessEqual(v('+1 832 201 8856'), True)
-
-    def test_isZipCode(self):
-        v = validators.isZipCode
-        self.failUnlessEqual(v('03750'), True)
-        self.failUnlessEqual(v('33701-4313', ignore=r'-'), True)
-
-    def test_isURL(self):
-        v = validators.isURL
-        self.failUnlessEqual(v('http://foo.bar:8080/manage'), True)
-        self.failUnlessEqual(v('https://foo.bar:8080/manage'), True)
-        self.failUnlessEqual(v('irc://tiran@irc.freenode.net:6667/#plone'), True)
-        self.failUnlessEqual(v('fish://tiran:password@myserver/~/'), True)
-        self.failIfEqual(v('http://\n'), True)
-        self.failIfEqual(v('../foo/bar'), True)
-
-    def test_isEmail(self):
-        v = validators.isEmail
-        self.failUnlessEqual(v('test at test.com'), True)
-        self.failIfEqual(v('@foo.bar'), True)
-        self.failIfEqual(v('me'), True)
-        
-if __name__ == '__main__':
-    unittest.main()
\ No newline at end of file

Added: Sandbox/dirceu/megrok.form/src/megrok/form/tests/__init__.py
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/tests/__init__.py	                        (rev 0)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/tests/__init__.py	2008-02-04 17:11:23 UTC (rev 83501)
@@ -0,0 +1,7 @@
+import os.path
+import megrok.form
+from zope.app.testing.functional import ZCMLLayer
+
+ftesting_zcml = os.path.join(
+    os.path.dirname(megrok.form.__file__), 'ftesting.zcml')
+FunctionalLayer = ZCMLLayer(ftesting_zcml, __name__, 'FunctionalLayer')
\ No newline at end of file

Added: Sandbox/dirceu/megrok.form/src/megrok/form/tests/test_constraints.py
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/tests/test_constraints.py	                        (rev 0)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/tests/test_constraints.py	2008-02-04 17:11:23 UTC (rev 83501)
@@ -0,0 +1,51 @@
+import unittest
+from megrok.form import constraints
+
+class TestConstraints(unittest.TestCase):
+
+    def test_isSSN(self):
+        v = constraints.isSSN
+        self.failUnlessEqual(v('111223333'), True)
+        self.failUnlessEqual(v('111-22-3333', ignore=r'-'), True)
+
+    def test_isUSPhoneNumber(self):
+        v = constraints.isUSPhoneNumber
+        self.failUnlessEqual(v('(212) 555-1212',
+                               ignore=r'[\s\(\)\-]'), True)
+        self.failUnlessEqual(v('2125551212',
+                               ignore=r'[\s\(\)\-]'), True)
+
+        self.failUnlessEqual(v('(212) 555-1212'), True)
+        
+    def test_isInternationalPhoneNumber(self):
+        v = constraints.isInternationalPhoneNumber
+        self.failUnlessEqual(v('+1 713 942 2377'), True)
+        self.failUnlessEqual(v('+1 832 201 8856'), True)
+
+    def test_isZipCode(self):
+        v = constraints.isZipCode
+        self.failUnlessEqual(v('03750'), True)
+        self.failUnlessEqual(v('33701-4313', ignore=r'-'), True)
+
+    def test_isURL(self):
+        v = constraints.isURL
+        self.failUnlessEqual(v('http://foo.bar:8080/manage'), True)
+        self.failUnlessEqual(v('https://foo.bar:8080/manage'), True)
+        self.failUnlessEqual(v('irc://tiran@irc.freenode.net:6667/#plone'), True)
+        self.failUnlessEqual(v('fish://tiran:password@myserver/~/'), True)
+        self.failIfEqual(v('http://\n'), True)
+        self.failIfEqual(v('../foo/bar'), True)
+
+    def test_isEmail(self):
+        v = constraints.isEmail
+        self.failUnlessEqual(v('test at test.com'), True)
+        self.failIfEqual(v('@foo.bar'), True)
+        self.failIfEqual(v('me'), True)
+
+def test_suite():
+    tests = ('test_isSSN', 'test_isUSPhoneNumber', 'test_isInternationalPhoneNumber', 
+             'test_isZipCode', 'test_isURL', 'test_isEmail')
+    return unittest.TestSuite(map(TestConstraints, tests))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')
\ No newline at end of file

Added: Sandbox/dirceu/megrok.form/src/megrok/form/tests/test_form.py
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/tests/test_form.py	                        (rev 0)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/tests/test_form.py	2008-02-04 17:11:23 UTC (rev 83501)
@@ -0,0 +1,78 @@
+import grok
+from zope import component, interface, schema
+from zope.publisher.browser import TestRequest
+from zope.schema.interfaces import ConstraintNotSatisfied
+from megrok.form.fields import Email, Image, HTML, File
+import unittest
+
+class MeGrokFormTest(grok.Application, grok.Container):
+    pass
+
+class IPerson(interface.Interface):
+    """ A simple class used to show how to use widgets and fields from megrok.form
+    """
+    name = schema.TextLine(title=u"Name")
+    email = Email(title=u"Email")
+    picture = Image(title=u"Picture")
+    description = HTML(title=u"Description")
+    birthday = schema.Date(title=u"Birthday")
+    resume = File(title=u"Resume")
+
+class Person(grok.Model):
+    interface.implements(IPerson)
+
+    def __init__(self, name, email, picture, description, birthday, resume):
+        self.name = name
+        self.email = email
+        self.picture = picture
+        self.description = description
+        self.birthday = birthday
+        self.resume = resume
+
+class AddPerson(grok.AddForm):
+    grok.context(MeGrokFormTest)
+    form_fields = grok.AutoFields(Person)
+
+    @grok.action('Add person')
+    def add(self, **data):
+        obj = Person(**data)
+        name = data['name'].lower().replace(' ', '_')
+        self.context[name] = obj
+
+class Edit(grok.EditForm):
+    grok.context(Person)
+    form_fields = grok.AutoFields(Person)
+
+class Index(grok.DisplayForm):
+    grok.context(Person)
+
+class MeGrokFormTests(unittest.TestCase):
+    def test_widgets(self):
+        """
+        Assures that the correct widgets are being used
+        
+        FIXME: This test sucks. Add a doctests for each widget.
+        """
+        grok.grok('megrok.form.tests')
+        view = component.getMultiAdapter((MeGrokFormTest(), TestRequest()), name='addperson')
+        rendered_html = u"""<html>\n<head>\n</head>\n\n<body>\n<form action="http://127.0.0.1" method="post"\n      class="edit-form" enctype="multipart/form-data">\n\n  \n\n  \n\n  <table class="form-fields">\n    <tbody>\n      \n        <tr>\n          <td class="label">\n            \n            <label for="form.name">\n              <span class="required">*</span><span>Name</span>\n            </label>\n          </td>\n          <td class="field">\n            <div class="widget"><input class="textType" id="form.name" name="form.name" size="20" type="text" value=""  /></div>\n            \n          </td>\n        </tr>\n      \n      \n        <tr>\n          <td class="label">\n            \n            <label for="form.email">\n              <span class="required">*</span><span>Email</span>\n            </label>\n          </td>\n          <td class="field">\n            <div class="widget"><input class="textType" id="form.email" name="form.email" size="20" type="text" value=""  /></div>\n            \n          </td>\n        </tr>\n      \n      \n        <tr>\n          <td class="label">\n            \n            <label for="form.picture">\n              <span class="required">*</span><span>Picture</span>\n            </label>\n          </td>\n          <td class="field">\n            <div class="widget">\n\t<input type="hidden" value="" name="form.picture.used"\n        id="form.picture.used" />\n\t\n\t\n\t<div>\n\t\t<input type="file" maxlength="True" class="" size="30"\n         name="form.picture" id="form.picture" />\n\t\t\n\t</div>\n</div>\n            \n          </td>\n        </tr>\n      \n      \n        <tr>\n          <td class="label">\n            \n            <label for="form.description">\n              <span class="required">*</span><span>Description</span>\n            </label>\n          </td>\n          <td class="field">\n            <div class="widget"><textarea cols="60" id="form.description" name="form.description" rows="15" ></textarea><script type="text/javascript">\ntinyMCE.init({ \nmode : "exact", \nelements : "form.description"\n}\n);\n</script>\n</div>\n            \n          </td>\n        </tr>\n      \n      \n        <tr>\n          <td class="label">\n            \n            <label for="form.birthday">\n              <span class="required">*</span><span>Birthday</span>\n            </label>\n          </td>\n          <td class="field">\n            <div class="widget">\n<input class="textType" id="form.birthday" name="form.birthday" size="10" type="text" value=""  />\n<input type="button" value="..." id="form.birthday_trigger">\n<script type="text/javascript">\n  \n  \n  Calendar.setup({\n  inputField: \'form.birthday\',\n  button: \'form.birthday_trigger\',\n  ifFormat: \'%Y-%m-%d\'\n});\n\n</script>\n</div>\n            \n          </td>\n        </tr>\n      \n      \n        <tr>\n          <td class="label">\n            \n            <label for="form.resume">\n              <span class="required">*</span><span>Resume</span>\n            </label>\n          </td>\n          <td class="field">\n            <div class="widget">\n\t<input type="hidden" value="" name="form.resume.used"\n        id="form.resume.used" />\n\t\n\t\n\t<div>\n\t\t<input type="file" maxlength="True" class="" size="30"\n         name="form.resume" id="form.resume" />\n\t\t\n\t</div>\n</div>\n            \n          </td>\n        </tr>\n      \n    </tbody>\n  </table>\n\n  <div id="actionsView">\n    <span class="actionButtons">\n      <input type="submit" id="form.actions.41646420706572736f6e" name="form.actions.41646420706572736f6e" value="Add person" class="button" />\n    </span>\n  </div>\n</form>\n\n</body>\n</html>\n"""
+        self.assertEquals(view.render(), rendered_html)
+        
+    def test_email_default_constraint(self):
+        """
+        Assures that the default constraint for the Email field is working
+        """
+        from megrok.form.fields import Email
+        email = Email(title=u'Email')
+        self.assertRaises(ConstraintNotSatisfied, email.validate, u'thisisnotanemailaddress')
+        email.validate(u'thisisanemailaddress at email.com')        
+
+def test_suite():
+    from megrok.form.tests import FunctionalLayer
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(MeGrokFormTests))
+    suite.layer = FunctionalLayer
+    return suite
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Deleted: Sandbox/dirceu/megrok.form/src/megrok/form/validators.py
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/validators.py	2008-02-04 16:56:33 UTC (rev 83500)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/validators.py	2008-02-04 17:11:23 UTC (rev 83501)
@@ -1,48 +0,0 @@
-import re
-
-def validate_expression(value, expression, **kwargs):
-    ignore = kwargs.get('ignore', None)
-    if ignore:
-        if isinstance(ignore, basestring):
-            ignore = re.compile(ignore)
-        value = ignore.sub('', value)
-    if expression.match(value):
-        return True
-    return False
-    
-def isSSN(value, **kwargs):
-    expr = re.compile(r'^\d{9}$')
-    errmsg = 'is not a well formed SSN.'
-    return validate_expression(value, expr, errmsg=errmsg, **kwargs)
-
-def isUSPhoneNumber(value, **kwargs):
-    expr = re.compile(r'^\d{10}$')
-    if not kwargs.get('ignore', None):
-        kwargs['ignore'] = re.compile(r'[\(\)\-\s]')
-    errmsg = 'is not a valid us phone number.'
-    return validate_expression(value, expr, errmsg=errmsg, **kwargs)
-    
-def isInternationalPhoneNumber(value, **kwargs):
-    expr = re.compile(r'^\d+$')
-    if not kwargs.get('ignore', None):
-        kwargs['ignore'] = re.compile(r'[\(\)\-\s\+]')
-    errmsg = 'is not a valid international phone number.'
-    return validate_expression(value, expr, errmsg=errmsg, **kwargs)
-    
-def isZipCode(value, **kwargs):
-    expr = re.compile(r'^(\d{5}|\d{9})$')
-    errmsg = 'is not a valid zip code.'
-    return validate_expression(value, expr, errmsg=errmsg, **kwargs)
-    
-def isURL(value, **kwargs):
-    protocols = ('http', 'ftp', 'irc', 'news', 'imap', 'gopher', 'jabber',
-        'webdav', 'smb', 'fish', 'ldap', 'pop3', 'smtp', 'sftp', 'ssh'
-    )
-    expr = re.compile(r'(%s)s?://[^\s\r\n]+' % '|'.join(protocols))
-    errmsg = 'is not a valid url.'
-    return validate_expression(value, expr, errmsg=errmsg, **kwargs)
-    
-def isEmail(value, **kwargs):
-    expr = re.compile(r"^(\w&.%#$&'\*+-/=?^_`{}|~]+!)*[\w&.%#$&'\*+-/=?^_`{}|~]+@(([0-9a-z]([0-9a-z-]*[0-9a-z])?\.)+[a-z]{2,6}|([0-9]{1,3}\.){3}[0-9]{1,3})$", re.IGNORECASE)
-    errmsg = 'is not a valid email address.'
-    return validate_expression(value, expr, errmsg=errmsg, **kwargs)
\ No newline at end of file



More information about the Checkins mailing list