test and fix guess_field, some pylint fixes tls-sprint
authorsylvain.thenault@logilab.fr
Thu, 12 Mar 2009 16:33:29 +0100
branchtls-sprint
changeset 1095 6917ebe281e9
parent 1094 b42340dda74b
child 1096 e1fe98850bf7
test and fix guess_field, some pylint fixes
web/formfields.py
web/test/unittest_formfields.py
--- a/web/formfields.py	Thu Mar 12 16:32:19 2009 +0100
+++ b/web/formfields.py	Thu Mar 12 16:33:29 2009 +0100
@@ -6,6 +6,19 @@
 """
 __docformat__ = "restructuredtext en"
 
+from datetime import datetime
+
+from logilab.mtconverter import html_escape
+from yams.constraints import SizeConstraint, StaticVocabularyConstraint
+
+from cubicweb.schema import FormatConstraint
+from cubicweb.utils import ustrftime
+from cubicweb.common import tags, uilib
+from cubicweb.web import INTERNAL_FIELD_VALUE
+from cubicweb.web.formwidgets import (HiddenInput, TextInput, FileInput, PasswordInput,
+                                      TextArea, FCKEditor, Radio, Select,
+                                      DateTimePicker) 
+
 class Field(object):
     """field class is introduced to control what's displayed in edition form
     """
@@ -15,7 +28,7 @@
 
     def __init__(self, name=None, id=None, label=None,
                  widget=None, required=False, initial=None,
-                 choices=None, help=None, eidparam=False):
+                 choices=None, help=None, eidparam=False, role='subject'):
         self.required = required
         if widget is not None:
             self.widget = widget
@@ -28,7 +41,7 @@
         self.choices = choices
         self.help = help
         self.eidparam = eidparam
-        self.role = 'subject'
+        self.role = role
         # global fields ordering in forms
         self.creation_rank = Field.creation_rank
         Field.creation_rank += 1
@@ -125,7 +138,8 @@
                 # else we want a format selector
                 # XXX compute vocabulary
                 widget = Select
-                choices = [(req._(format), format) for format in FormatConstraint().vocabulary(req=req)]
+                fcstr = FormatConstraint()
+                choices = [(req._(fmt), fmt) for fmt in fcstr.vocabulary(req=req)]
             field = StringField(name=self.name + '_format', widget=widget,
                                 choices=choices)
             req.data[self] = field
@@ -175,7 +189,7 @@
         if self.format_field or self.encoding_field:
             divid = '%s-advanced' % form.context[self]['name']
             wdgs.append(u'<a href="%s" title="%s"><img src="%s" alt="%s"/></a>' %
-                        (html_escape(toggle_action(divid)),
+                        (html_escape(uilib.toggle_action(divid)),
                          form.req._('show advanced fields'),
                          html_escape(form.req.build_url('data/puce_down.png')),
                          form.req._('show advanced fields')))
@@ -248,7 +262,7 @@
 
 class FloatField(IntField):    
     def format_single_value(self, req, value):
-        formatstr = entity.req.property_value('ui.float-format')
+        formatstr = req.property_value('ui.float-format')
         if value is None:
             return u''
         return formatstr % float(value)
@@ -289,9 +303,8 @@
         super(RelationField, self).__init__(**kwargs)
 
     @staticmethod
-    def fromcardinality(card, role, **kwargs):
-        return RelationField(widget=Select(multiple=card in '*+'),
-                             **kwargs)
+    def fromcardinality(card, **kwargs):
+        return RelationField(widget=Select(multiple=card in '*+'), **kwargs)
         
     def vocabulary(self, form):
         entity = form.entity
@@ -325,47 +338,56 @@
                                **kwargs)
         if isinstance(cstr, SizeConstraint) and cstr.max is not None:
             if cstr.max > 257:
-                field = textfield_from_constraint(cstr, **kwargs)
+                rows_cols_from_constraint(cstr, kwargs)
+                field = TextField(**kwargs)
             else:
                 field = StringField(max_length=cstr.max, **kwargs)
     return field or TextField(**kwargs)
-        
+
 
-def textfield_from_constraint(constraint, **kwargs):
-    if 256 < constraint.max < 513:
+def rows_cols_from_constraint(constraint, kwargs):
+    if constraint.max < 513:
         rows, cols = 5, 60
     else:
         rows, cols = 10, 80
-    return TextField(rows, cols, **kwargs)
+    kwargs.setdefault('rows', rows)
+    kwargs.setdefault('cols', cols)
 
 
-def find_field(eclass, subjschema, rschema, role='subject'):
+def guess_field(eclass, rschema, role='subject', **kwargs):
     """return the most adapated widget to edit the relation
     'subjschema rschema objschema' according to information found in the schema
     """
     fieldclass = None
+    eschema = eclass.e_schema
     if role == 'subject':
-        objschema = rschema.objects(subjschema)[0]
-        cardidx = 0
+        targetschema = rschema.objects(eschema)[0]
+        card = rschema.rproperty(eschema, targetschema, 'cardinality')[0]
     else:
-        objschema = rschema.subjects(subjschema)[0]
-        cardidx = 1
-    card = rschema.rproperty(subjschema, objschema, 'cardinality')[cardidx]
-    required = card in '1+'
-    if rschema in eclass.widgets:
-        fieldclass = eclass.widgets[rschema]
-        if isinstance(fieldclass, basestring):
-            return StringField(name=rschema.type)
-    elif not rschema.is_final():
-        return RelationField.fromcardinality(card, role,name=rschema.type,
-                                             required=required)
-    else:
-        fieldclass = FIELDS[objschema]
-    if fieldclass is StringField:
-        constraints = rschema.rproperty(subjschema, objschema, 'constraints')
-        return stringfield_from_constraints(constraints, name=rschema.type,
-                                            required=required)
-    return fieldclass(name=rschema.type, required=required)
+        targetschema = rschema.subjects(eschema)[0]
+        card = rschema.rproperty(targetschema, eschema, 'cardinality')[1]
+    kwargs['required'] = card in '1+'
+    kwargs['name'] = rschema.type
+    if rschema.is_final():
+        if rschema in eschema.format_fields:
+            return None
+        if targetschema == 'Password':
+            return StringField(widget=PasswordInput(), **kwargs)
+        if eschema.has_format(rschema):
+            constraints = rschema.rproperty(eschema, targetschema, 'constraints')
+            for cstr in constraints:
+                if isinstance(cstr, StaticVocabularyConstraint):
+                    raise Exception('rich text field with static vocabulary')
+                if isinstance(cstr, SizeConstraint) and cstr.max is not None:
+                    rows_cols_from_constraint(cstr, kwargs)
+            return RichTextField(**kwargs)
+        fieldclass = FIELDS[targetschema]
+        if fieldclass is StringField:
+            constraints = rschema.rproperty(eschema, targetschema, 'constraints')
+            return stringfield_from_constraints(constraints, **kwargs)
+        return fieldclass(**kwargs)
+    kwargs['role'] = role
+    return RelationField.fromcardinality(card, **kwargs)
 
 FIELDS = {
     'Boolean':  BooleanField,
@@ -379,4 +401,3 @@
     'String' :  StringField,
     'Time':     TimeField,
     }
-views/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/unittest_formfields.py	Thu Mar 12 16:33:29 2009 +0100
@@ -0,0 +1,64 @@
+"""unittests for cw.web.formfields"""
+
+from logilab.common.testlib import TestCase, unittest_main
+
+from cubicweb.devtools import TestServerConfiguration
+from cubicweb.entities.lib import Card
+from cubicweb.entities.authobjs import EUser
+from cubicweb.web.formwidgets import PasswordInput
+from cubicweb.web.formfields import *
+
+config = TestServerConfiguration('data')
+config.bootstrap_cubes()
+schema = config.load_schema()
+Card.schema = schema
+Card.__initialize__()
+EUser.schema = schema
+EUser.__initialize__()
+        
+class GuessFieldTC(TestCase):
+    
+    def test_card_fields(self):
+        title_field = guess_field(Card, schema['title'])
+        self.assertIsInstance(title_field, StringField)
+        self.assertEquals(title_field.required, True)
+        
+        synopsis_field = guess_field(Card, schema['synopsis'])
+        self.assertIsInstance(synopsis_field, TextField)
+        self.assertEquals(synopsis_field.required, False)
+        
+        content_field = guess_field(Card, schema['content'])
+        self.assertIsInstance(content_field, RichTextField)
+        self.assertEquals(content_field.required, False)
+        
+        content_format_field = guess_field(Card, schema['content_format'])
+        self.assertEquals(content_format_field, None)
+        
+        wikiid_field = guess_field(Card, schema['wikiid'])
+        self.assertIsInstance(wikiid_field, StringField)
+        self.assertEquals(wikiid_field.required, False)
+
+        
+    def test_euser_fields(self):
+        upassword_field = guess_field(EUser, schema['upassword'])
+        self.assertIsInstance(upassword_field, StringField)
+        self.assertIsInstance(upassword_field.widget, PasswordInput)
+        self.assertEquals(upassword_field.required, True)
+
+        last_login_time_field = guess_field(EUser, schema['last_login_time'])
+        self.assertIsInstance(last_login_time_field, DateTimeField)
+        self.assertEquals(last_login_time_field.required, False)
+
+        in_group_field = guess_field(EUser, schema['in_group'])
+        self.assertIsInstance(in_group_field, RelationField)
+        self.assertEquals(in_group_field.required, True)
+        self.assertEquals(in_group_field.role, 'subject')
+
+        owned_by_field = guess_field(EUser, schema['owned_by'], 'object')
+        self.assertIsInstance(owned_by_field, RelationField)
+        self.assertEquals(owned_by_field.required, False)
+        self.assertEquals(owned_by_field.role, 'object')
+
+    
+if __name__ == '__main__':
+    unittest_main()