# HG changeset patch # User sylvain.thenault@logilab.fr # Date 1236872009 -3600 # Node ID 6917ebe281e9b0e76c9ba5288f1921d8a836bf79 # Parent b42340dda74bd555c9d387b34b0ad45f4dcea991 test and fix guess_field, some pylint fixes diff -r b42340dda74b -r 6917ebe281e9 web/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'%s' % - (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/ diff -r b42340dda74b -r 6917ebe281e9 web/test/unittest_formfields.py --- /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()