Changeset 239

Show
Ignore:
Timestamp:
07/05/06 09:53:11 (3 years ago)
Author:
matt
Message:

Move the Component and ComponentWidget? classes to correct/better modules.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/composite/formal/__init__.py

    r231 r239  
    1212from formal.validation import * 
    1313from formal.widget import * 
     14from formal.widgets.composite import * 
    1415from formal.widgets.restwidget import * 
    1516from formal.widgets.multiselect import * 
     
    4546registerAdapter(TextInput, Time, iformal.IWidget) 
    4647registerAdapter(FileUploadRaw, File, iformal.IWidget) 
     48registerAdapter(CompositeWidget, Composite, iformal.IWidget) 
    4749registerAdapter(SequenceKeyLabelAdapter, tuple, iformal.IKey) 
    4850registerAdapter(SequenceKeyLabelAdapter, tuple, iformal.ILabel) 
  • branches/composite/formal/examples/composite.py

    r237 r239  
    1 from zope.interface import implements 
    2 from twisted.python.components import registerAdapter 
    3 from nevow import inevow, tags as T 
    4 import formal, formal.iformal, formal.types, formal.widget, formal.util 
     1import formal 
    52from formal.examples import main 
    6  
    7  
    8  
    9 ##### 
    10 # TODO: 
    11 # 
    12 #  * composition labels, and position (?) 
    13 #  * composition widgets 
    14 #  * composition errors (?) 
    15 #  * composition description (?) 
    16 #  * Validate XHTML 
    17 # 
    18  
    19  
    20  
    21 class Composite(formal.types.Type): 
    22  
    23     def __init__(self, composition, *a, **k): 
    24         super(Composite, self).__init__(*a, **k) 
    25         self.composition = composition 
    26  
    27  
    28     def validate(self, value): 
    29  
    30         # Check we have the correct number of values, otherwise the final value 
    31         # could be completely wrong because we're relying on zip to build the 
    32         # dict. 
    33         if len(value) != len(self.composition): 
    34             raise ValueError("Incorrect number of values to validate") 
    35  
    36         # If nothing has been entered then we'll have a sequence of None 
    37         # instances, in which case my value if None (not a sequence). If there 
    38         # is anything other than None in the sequence then pass validation on to 
    39         # the composite types. 
    40         if not filter(None, value): 
    41             value = None 
    42         else: 
    43             value = dict([ 
    44                     (name, type.validate(value)) 
    45                     for (name, type), value in zip(self.composition, value)]) 
    46  
    47         # Allow normal validation to run on the new value 
    48         return super(Composite, self).validate(value) 
    49  
    50  
    51  
    52 class CompositeWidget(object): 
    53     implements(formal.iformal.IWidget) 
    54  
    55  
    56     labels = None 
    57     widgetFactories = None 
    58  
    59  
    60     def __init__(self, composite, labels=None, widgetFactories=None): 
    61         self.composite = composite 
    62         if labels is not None: 
    63             self.labels = labels 
    64         if widgetFactories is not None: 
    65             self.widgetFactories = widgetFactories 
    66  
    67  
    68     def render(self, ctx, key, args, errors): 
    69         for name, type in self.composite.composition: 
    70             childKey = '.'.join([key, name]) 
    71             yield T.div(class_=name)[ 
    72                 T.label(for_=formal.util.render_cssid(childKey))[ 
    73                     formal.util.titleFromName(name) 
    74                     ], 
    75                 formal.iformal.IWidget(type).render(ctx, childKey, args, errors) 
    76                 ] 
    77  
    78  
    79     def renderImmutable(self, ctx, key, args, errors): 
    80         for name, type in self.composite.composition: 
    81             childKey = '.'.join([key, name]) 
    82             yield T.div(class_=name)[ 
    83                 T.label[formal.util.titleFromName(name)], 
    84                 formal.iformal.IWidget(type).renderImmutable(ctx, childKey, 
    85                         args, errors) 
    86                 ] 
    87  
    88  
    89     def processInput(self, ctx, key, args): 
    90         value = [] 
    91         for name, type in self.composite.composition: 
    92             childKey = '.'.join([key, name]) 
    93             value.append(formal.iformal.IWidget(type).processInput(ctx, 
    94                 childKey, args)) 
    95         return tuple(value) 
    96  
    97  
    98  
    99 registerAdapter(CompositeWidget, Composite, formal.iformal.IWidget) 
    1003 
    1014 
     
    11316        # Add a required name where the family name is required but the first 
    11417        # name is optional. 
    115         form.add(formal.Field('name', Composite([ 
     18        form.add(formal.Field('name', formal.Composite([ 
    11619            ('family', formal.String(required=True)), 
    11720            ('first', formal.String())], 
     
    12023        # Add an optional temperature field where, once entered, both values 
    12124        # must be entered. 
    122         form.add(formal.Field('temperature', Composite([ 
     25        form.add(formal.Field('temperature', formal.Composite([ 
    12326            ('temperature', formal.Integer(required=True)), 
    12427            ('units', formal.String(required=True))]))) 
    12528 
    12629        # Add a required height field where both values are also required. 
    127         form.add(formal.Field('height', Composite([ 
     30        form.add(formal.Field('height', formal.Composite([ 
    12831            ('feet', formal.Integer(required=True)), 
    12932            ('inches', formal.Integer(required=True))], 
  • branches/composite/formal/test/test_types.py

    r237 r239  
    127127 
    128128 
    129 from formal.examples.composite import Composite 
    130  
    131129class TestComposite(unittest.TestCase): 
    132130 
    133131    def test_one(self): 
    134         self.assertEquals(Composite([ 
     132        self.assertEquals(formal.Composite([ 
    135133            ('foo', formal.String()) 
    136134            ]).validate([u'bar']), {'foo': u'bar'}) 
    137         self.assertEquals(Composite([ 
     135        self.assertEquals(formal.Composite([ 
    138136            ('foo', formal.Integer()) 
    139137            ]).validate([123]), {'foo': 123}) 
    140138 
    141139    def test_multisame(self): 
    142         self.assertEquals(Composite([ 
     140        self.assertEquals(formal.Composite([ 
    143141            ('foo', formal.String()), 
    144142            ('bar', formal.String()) 
    145143            ]).validate([u'foo', u'bar']), {'foo': u'foo', 'bar': u'bar'}) 
    146         self.assertEquals(Composite([ 
     144        self.assertEquals(formal.Composite([ 
    147145            ('foo', formal.Integer()), 
    148146            ('bar', formal.Integer()), 
     
    150148 
    151149    def test_multidiff(self): 
    152         self.assertEquals(Composite([ 
     150        self.assertEquals(formal.Composite([ 
    153151            ('foo', formal.String()), 
    154152            ('bar', formal.Integer()) 
    155153            ]).validate([u'foo', 123]), {'foo': u'foo', 'bar': 123}) 
    156         self.assertEquals(Composite([ 
     154        self.assertEquals(formal.Composite([ 
    157155            ('foo', formal.String()), 
    158156            ('bar', formal.Integer()) 
     
    160158 
    161159    def test_none(self): 
    162         self.assertEquals(Composite([('foo', 
     160        self.assertEquals(formal.Composite([('foo', 
    163161            formal.String())]).validate([None]), None) 
    164         self.assertEquals(Composite([ 
     162        self.assertEquals(formal.Composite([ 
    165163            ('foo', formal.String()), 
    166164            ('bar', formal.Integer()) 
     
    169167    def test_missing(self): 
    170168        missing = object() 
    171         self.assertEquals(Composite([('foo', 
     169        self.assertEquals(formal.Composite([('foo', 
    172170            formal.String())], missing=missing).validate([None]), missing) 
    173171 
    174172    def test_notrequired_required(self): 
    175         self.assertEquals(Composite([ 
     173        self.assertEquals(formal.Composite([ 
    176174            ('foo', formal.String(required=True)) 
    177175            ]).validate([u'foo']), {'foo': u'foo'}) 
    178         self.assertEquals(Composite([ 
     176        self.assertEquals(formal.Composite([ 
    179177            ('foo', formal.String(required=True)), 
    180178            ('bar', formal.Integer(required=True)) 
    181179            ]).validate([u'foo', 123]), {'foo': u'foo', 'bar': 123}) 
    182         self.assertEquals(Composite([ 
     180        self.assertEquals(formal.Composite([ 
    183181            ('foo', formal.String(required=True)) 
    184182            ]).validate([None]), None) 
    185         self.assertEquals(Composite([ 
     183        self.assertEquals(formal.Composite([ 
    186184            ('foo', formal.String(required=True)), 
    187185            ('bar', formal.Integer(required=True)) 
     
    189187 
    190188    def test_notrequired_onerequired(self): 
    191         self.assertEquals(Composite([ 
     189        self.assertEquals(formal.Composite([ 
    192190            ('foo', formal.String(required=True)), 
    193191            ('bar', formal.Integer()) 
    194192            ]).validate([u'foo', None]), {'foo': u'foo', 'bar': None}) 
    195         self.assertEquals(Composite([ 
     193        self.assertEquals(formal.Composite([ 
    196194            ('foo', formal.String(required=True)), 
    197195            ('bar', formal.Integer()) 
    198196            ]).validate([None, None]), None) 
    199         self.assertRaises(formal.FieldValidationError, Composite([ 
     197        self.assertRaises(formal.FieldValidationError, formal.Composite([ 
    200198            ('foo', formal.String(required=True)), 
    201199            ('bar', formal.Integer()) 
     
    203201 
    204202    def test_required(self): 
    205         self.assertEquals(Composite([ 
     203        self.assertEquals(formal.Composite([ 
    206204            ('foo', formal.String()) 
    207205            ], required=True).validate([u'foo']), {'foo': u'foo'}) 
    208         self.assertEquals(Composite([ 
     206        self.assertEquals(formal.Composite([ 
    209207            ('foo', formal.String()), 
    210208            ('bar', formal.Integer()) 
    211209            ], required=True).validate([u'foo', None]), {'foo': u'foo', 'bar': None}) 
    212         self.assertEquals(Composite([ 
     210        self.assertEquals(formal.Composite([ 
    213211            ('foo', formal.String()), 
    214212            ('bar', formal.Integer()) 
    215213            ], required=True).validate([None, 123]), {'foo': None, 'bar': 123}) 
    216         self.assertRaises(formal.FieldRequiredError, Composite([ 
     214        self.assertRaises(formal.FieldRequiredError, formal.Composite([ 
    217215            ('foo', formal.String()) 
    218216            ], required=True).validate, [None]) 
    219         self.assertRaises(formal.FieldRequiredError, Composite([ 
     217        self.assertRaises(formal.FieldRequiredError, formal.Composite([ 
    220218            ('foo', formal.String()), 
    221219            ('bar', formal.Integer()) 
     
    223221 
    224222    def test_required_onerequired(self): 
    225         self.assertEquals(Composite([ 
     223        self.assertEquals(formal.Composite([ 
    226224            ('foo', formal.String(required=True)), 
    227225            ('bar', formal.Integer()) 
    228226            ], required=True).validate([u'foo', None]), {'foo': u'foo', 'bar': None}) 
    229         self.assertEquals(Composite([ 
     227        self.assertEquals(formal.Composite([ 
    230228            ('foo', formal.String(required=True)), 
    231229            ('bar', formal.Integer()) 
    232230            ], required=True).validate([u'foo', 123]), {'foo': u'foo', 'bar': 123}) 
    233         self.assertRaises(formal.FieldRequiredError, Composite([ 
     231        self.assertRaises(formal.FieldRequiredError, formal.Composite([ 
    234232            ('foo', formal.String(required=True)), 
    235233            ('bar', formal.Integer()) 
    236234            ], required=True).validate, [None, None]) 
    237         self.assertRaises(formal.FieldRequiredError, Composite([ 
     235        self.assertRaises(formal.FieldRequiredError, formal.Composite([ 
    238236            ('foo', formal.String(required=True)), 
    239237            ('bar', formal.Integer()) 
     
    241239 
    242240    def test_required_allrequired(self): 
    243         self.assertRaises(formal.FieldRequiredError, Composite([ 
     241        self.assertRaises(formal.FieldRequiredError, formal.Composite([ 
    244242            ('foo', formal.String(required=True)) 
    245243            ], required=True).validate, [None]) 
    246         self.assertRaises(formal.FieldRequiredError, Composite([ 
     244        self.assertRaises(formal.FieldRequiredError, formal.Composite([ 
    247245            ('foo', formal.String(required=True)), 
    248246            ('bar', formal.Integer(required=True)) 
    249247            ], required=True).validate, [None, None]) 
    250         self.assertRaises(formal.FieldRequiredError, Composite([ 
     248        self.assertRaises(formal.FieldRequiredError, formal.Composite([ 
    251249            ('foo', formal.String(required=True)), 
    252250            ('bar', formal.Integer(required=True)) 
     
    254252 
    255253    def test_wrongNumberOfValues(self): 
    256         self.assertRaises(ValueError, Composite([ 
     254        self.assertRaises(ValueError, formal.Composite([ 
    257255            ('foo', formal.Integer()), 
    258256            ('bar', formal.String()), 
  • branches/composite/formal/types.py

    r196 r239  
    132132 
    133133 
     134 
     135class Composite(Type): 
     136 
     137 
     138    def __init__(self, composition, *a, **k): 
     139        super(Composite, self).__init__(*a, **k) 
     140        self.composition = composition 
     141 
     142 
     143    def validate(self, value): 
     144 
     145        # Check we have the correct number of values, otherwise the final value 
     146        # could be completely wrong because we're relying on zip to build the 
     147        # dict. 
     148        if len(value) != len(self.composition): 
     149            raise ValueError("Incorrect number of values to validate") 
     150 
     151        # If nothing has been entered then we'll have a sequence of None 
     152        # instances, in which case my value if None (not a sequence). If there 
     153        # is anything other than None in the sequence then pass validation on to 
     154        # the composite types. 
     155        if not filter(None, value): 
     156            value = None 
     157        else: 
     158            value = dict([ 
     159                    (name, type.validate(value)) 
     160                    for (name, type), value in zip(self.composition, value)]) 
     161 
     162        # Allow normal validation to run on the new value 
     163        return super(Composite, self).validate(value) 
     164 
     165 
     166 
    134167__all__ = [ 
    135     'Boolean', 'Date', 'File', 'Float', 'Integer', 'Sequence', 'String', 'Time', 
     168    'Boolean', 'Composite', 'Date', 'File', 'Float', 'Integer', 'Sequence', 
     169    'String', 'Time', 
    136170    ] 
    137171