Changeset 78:c85ce41a75bc


Ignore:
Timestamp:
Jan 5, 2010, 11:46:50 AM (11 years ago)
Author:
Ralph Meijer <ralphm@…>
Branch:
default
Message:

Add missing tests for Data Forms and correct some minor issues.

Location:
wokkel
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • wokkel/data_form.py

    r56 r78  
    11# -*- test-case-name: wokkel.test.test_data_form -*-
    22#
    3 # Copyright (c) 2003-2009 Ralph Meijer
     3# Copyright (c) 2003-2010 Ralph Meijer
    44# See LICENSE for details.
    55
     
    252252
    253253        for value in self.values:
    254             if self.fieldType == 'boolean':
     254            if isinstance(value, bool):
    255255                value = unicode(value).lower()
    256             elif self.fieldType in ('jid-single', 'jid-multi'):
    257                 value = value.full()
     256            else:
     257                value = unicode(value)
    258258
    259259            field.addElement('value', content=value)
     
    344344    Data Form.
    345345
    346     There are two similarly named properties of forms. The L{formType} is the
     346    There are two similarly named properties of forms. The C{formType} is the
    347347    the so-called type of the form, and is set as the C{'type'} attribute
    348348    on the form's root element.
     
    352352    special hidden field named C{'FORM_TYPE'}, to put the names of all
    353353    other fields in the namespace of the value of that field. This namespace
    354     is recorded in the L{formNamespace} instance variable.
     354    is recorded in the C{formNamespace} instance variable.
    355355
    356356    @ivar formType: Type of form. One of C{'form'}, C{'submit'}, {'cancel'},
    357357                    or {'result'}.
    358     @type formType: C{str}.
     358    @type formType: C{str}
     359
     360    @ivar title: Natural language title of the form.
     361    @type title: C{unicode}
     362
     363    @ivar instructions: Natural language instructions as a list of C{unicode}
     364        strings without line breaks.
     365    @type instructions: C{list}
     366
    359367    @ivar formNamespace: The optional namespace of the field names for this
    360                          form. This goes in the special field named
    361                          C{'FORM_TYPE'}, if set.
     368        form. This goes in the special field named C{'FORM_TYPE'}, if set.
    362369    @type formNamespace: C{str}.
    363     @ivar fields: Dictionary of fields that have a name. Note that this is
    364                   meant to be used for reading, only. One should use
    365                   L{addField} for adding fields.
     370
     371    @ivar fields: Dictionary of named fields. Note that this is meant to be
     372        used for reading, only. One should use L{addField} or L{makeFields} and
     373        L{removeField} for adding and removing fields.
    366374    @type fields: C{dict}
     375
     376    @ivar fieldList: List of all fields, in the order they are added. Like
     377        C{fields}, this is meant to be used for reading, only.
     378    @type fieldList: C{list}
    367379    """
    368380
     
    393405            r.append(", formNamespace=")
    394406            r.append(repr(self.formNamespace))
    395         if self.fields:
     407        if self.fieldList:
    396408            r.append(", fields=")
    397409            r.append(repr(self.fieldList))
     
    425437
    426438        for instruction in self.instructions:
    427             form.addElement('instruction', content=instruction)
     439            form.addElement('instructions', content=instruction)
    428440
    429441        if self.formNamespace is not None:
     
    478490        return form
    479491
     492
    480493    def getValues(self):
     494        """
     495        Extract values from the named form fields.
     496
     497        For all named fields, the corresponding value or values are
     498        returned in a dictionary keyed by the field name. For multi-value
     499        fields, the dictionary value is a list, otherwise a single value.
     500
     501        If a field has no type, and the field has multiple values, the value of
     502        the dictionary entry is the list of values. Otherwise, it will be a
     503        single value.
     504
     505        @rtype: C{dict}
     506        """
    481507        values = {}
    482508
    483509        for name, field in self.fields.iteritems():
    484             if len(field.values) > 1:
     510            if (field.fieldType in ('jid-multi', 'list-multi', 'text-multi') or
     511                (field.fieldType is None and len(field.values) > 1)):
    485512                value = field.values
    486513            else:
  • wokkel/test/test_data_form.py

    r56 r78  
    1 # Copyright (c) 2003-2009 Ralph Meijer
     1# Copyright (c) 2003-2010 Ralph Meijer
    22# See LICENSE for details.
    33
     
    2020
    2121    def test_toElement(self):
     22        """
     23        An option is an option element with a value child with the option value.
     24        """
     25        option = data_form.Option('value')
     26        element = option.toElement()
     27
     28        self.assertEqual('option', element.name)
     29        self.assertEqual(NS_X_DATA, element.uri)
     30        self.assertEqual(NS_X_DATA, element.value.uri)
     31        self.assertEqual('value', unicode(element.value))
     32        self.assertFalse(element.hasAttribute('label'))
     33
     34
     35    def test_toElementLabel(self):
     36        """
     37        A label is rendered as an attribute on the option element.
     38        """
    2239        option = data_form.Option('value', 'label')
    2340        element = option.toElement()
    24         self.assertEquals('option', element.name)
    25         self.assertEquals(NS_X_DATA, element.uri)
    26         self.assertEquals('label', element['label'])
    27         self.assertEquals('value', element.value.name)
    28         self.assertEquals(NS_X_DATA, element.value.uri)
    29         self.assertEquals('value', unicode(element.value))
     41
     42        self.assertEqual('option', element.name)
     43        self.assertEqual(NS_X_DATA, element.uri)
     44        self.assertEqual(NS_X_DATA, element.value.uri)
     45        self.assertEqual('value', unicode(element.value))
     46        self.assertEqual('label', element['label'])
     47
     48
     49    def test_fromElement(self):
     50        """
     51        An option has a child element with the option value.
     52        """
     53        element = domish.Element((NS_X_DATA, 'option'))
     54        element.addElement('value', content='value')
     55        option = data_form.Option.fromElement(element)
     56
     57        self.assertEqual('value', option.value)
     58        self.assertIdentical(None, option.label)
     59
     60
     61    def test_fromElementLabel(self):
     62        """
     63        An option label is an attribute on the option element.
     64        """
     65
     66        element = domish.Element((NS_X_DATA, 'option'))
     67        element.addElement('value', content='value')
     68        element['label'] = 'label'
     69        option = data_form.Option.fromElement(element)
     70
     71        self.assertEqual('label', option.label)
     72
     73
     74    def test_fromElementNoValue(self):
     75        """
     76        An option MUST have a value.
     77        """
     78        element = domish.Element((NS_X_DATA, 'option'))
     79        self.assertRaises(data_form.Error,
     80                          data_form.Option.fromElement, element)
     81
     82
     83    def test_repr(self):
     84        """
     85        The representation of an Option is equal to how it is created.
     86        """
     87        option = data_form.Option('value', 'label')
     88        self.assertEqual("""Option('value', 'label')""", repr(option))
    3089
    3190
     
    43102        self.assertEqual('text-single', field.fieldType)
    44103        self.assertEqual('test', field.var)
     104
     105
     106    def test_repr(self):
     107        """
     108        The repr of a field should be equal to its initialization.
     109        """
     110        field = data_form.Field('list-single', var='test', label='label',
     111                               desc='desc', required=True, value='test',
     112                               options=[data_form.Option('test')])
     113        self.assertEqual("""Field(fieldType='list-single', """
     114                         """var='test', label='label', """
     115                         """desc='desc', required=True, """
     116                         """values=['test'], """
     117                         """options=[Option('test')])""",
     118                         repr(field))
    45119
    46120
     
    131205
    132206    def test_toElementJID(self):
     207        """
     208        A JID value should render to text.
     209        """
    133210        field = data_form.Field(fieldType='jid-single', var='test',
    134211                                value=jid.JID(u'test@example.org'))
    135212        element = field.toElement()
    136213        self.assertEqual(u'test@example.org', unicode(element.value))
     214
     215
     216    def test_toElementJIDTextSingle(self):
     217        """
     218        A JID value should render to text if field type is text-single.
     219        """
     220        field = data_form.Field(fieldType='text-single', var='test',
     221                                value=jid.JID(u'test@example.org'))
     222        element = field.toElement()
     223        self.assertEqual(u'test@example.org', unicode(element.value))
     224
     225
     226    def test_toElementBoolean(self):
     227        """
     228        A boolean value should render to text.
     229        """
     230        field = data_form.Field(fieldType='boolean', var='test',
     231                                value=True)
     232        element = field.toElement()
     233        self.assertEqual(u'true', unicode(element.value))
     234
     235
     236    def test_toElementBooleanTextSingle(self):
     237        """
     238        A boolean value should render to text if the field type is text-single.
     239        """
     240        field = data_form.Field(var='test', value=True)
     241        element = field.toElement()
     242        self.assertEqual(u'true', unicode(element.value))
    137243
    138244
     
    251357        self.assertEquals(u'user@example.org', field.value)
    252358
     359
    253360    def test_fromElementValueJIDMalformed(self):
    254361        """
     
    275382        self.assertEquals(u'false', field.value)
    276383
     384
     385    def test_fromElementDesc(self):
     386        """
     387        Field descriptions are in a desc child element.
     388        """
     389        element = domish.Element((NS_X_DATA, 'field'))
     390        element.addElement('desc', content=u'My description')
     391        field = data_form.Field.fromElement(element)
     392        self.assertEqual(u'My description', field.desc)
     393
     394
     395    def test_fromElementOption(self):
     396        """
     397        Field descriptions are in a desc child element.
     398        """
     399        element = domish.Element((NS_X_DATA, 'field'))
     400        element.addElement('option').addElement('value', content=u'option1')
     401        element.addElement('option').addElement('value', content=u'option2')
     402        field = data_form.Field.fromElement(element)
     403        self.assertEqual(2, len(field.options))
     404
     405
     406    def test_fromElementRequired(self):
     407        """
     408        Required fields have a required child element.
     409        """
     410        element = domish.Element((NS_X_DATA, 'field'))
     411        element.addElement('required')
     412        field = data_form.Field.fromElement(element)
     413        self.assertTrue(field.required)
     414
     415
     416    def test_fromElementChildOtherNamespace(self):
     417        """
     418        Child elements from another namespace are ignored.
     419        """
     420        element = domish.Element((NS_X_DATA, 'field'))
     421        element['var'] = 'test'
     422        child = element.addElement(('myns', 'value'))
     423        field = data_form.Field.fromElement(element)
     424
     425        self.assertIdentical(None, field.value)
     426
     427
     428    def test_fromDict(self):
     429        """
     430        A named field with a value can be created by providing a dictionary.
     431        """
     432        fieldDict = {'var': 'test', 'value': 'text'}
     433        field = data_form.Field.fromDict(fieldDict)
     434        self.assertEqual('test', field.var)
     435        self.assertEqual('text', field.value)
     436
     437
     438    def test_fromDictFieldType(self):
     439        """
     440        The field type is set using the key 'type'.
     441        """
     442        fieldDict = {'type': 'boolean'}
     443        field = data_form.Field.fromDict(fieldDict)
     444        self.assertEqual('boolean', field.fieldType)
     445
     446
     447    def test_fromDictOptions(self):
     448        """
     449        The field options are set using the key 'options'.
     450
     451        The options are represented as a dictionary keyed by option,
     452        with the optional label as value.
     453        """
     454        fieldDict = {'options': {'value1': 'label1',
     455                                 'value2': 'label2'}}
     456        field = data_form.Field.fromDict(fieldDict)
     457        self.assertEqual(2, len(field.options))
     458        options = {}
     459        for option in field.options:
     460            options[option.value] = option.label
     461
     462        self.assertEqual(options, fieldDict['options'])
    277463
    278464
     
    289475        form = data_form.Form('result')
    290476        self.assertEqual('result', form.formType)
     477
    291478
    292479    def test_toElement(self):
     
    304491
    305492
     493    def test_toElementTitle(self):
     494        """
     495        A title is rendered as a child element with the title as CDATA.
     496        """
     497        form = data_form.Form('form', title='Bot configuration')
     498        element = form.toElement()
     499
     500        elements = list(element.elements())
     501        self.assertEqual(1, len(elements))
     502        title = elements[0]
     503        self.assertEqual('title', title.name)
     504        self.assertEqual(NS_X_DATA, title.uri)
     505        self.assertEqual('Bot configuration', unicode(title))
     506
     507
     508    def test_toElementInstructions(self):
     509        """
     510        Instructions are rendered as child elements with CDATA.
     511        """
     512        form = data_form.Form('form', instructions=['Fill out this form!'])
     513        element = form.toElement()
     514
     515        elements = list(element.elements())
     516        self.assertEqual(1, len(elements))
     517        instructions = elements[0]
     518        self.assertEqual('instructions', instructions.name)
     519        self.assertEqual(NS_X_DATA, instructions.uri)
     520        self.assertEqual('Fill out this form!', unicode(instructions))
     521
     522
     523    def test_toElementInstructionsMultiple(self):
     524        """
     525        Instructions render as one element per instruction, in order.
     526        """
     527        form = data_form.Form('form', instructions=['Fill out this form!',
     528                                                    'no really'])
     529        element = form.toElement()
     530
     531        elements = list(element.elements())
     532        self.assertEqual(2, len(elements))
     533        instructions1 = elements[0]
     534        instructions2 = elements[1]
     535        self.assertEqual('instructions', instructions1.name)
     536        self.assertEqual(NS_X_DATA, instructions1.uri)
     537        self.assertEqual('Fill out this form!', unicode(instructions1))
     538        self.assertEqual('instructions', instructions2.name)
     539        self.assertEqual(NS_X_DATA, instructions2.uri)
     540        self.assertEqual('no really', unicode(instructions2))
     541
     542
     543    def test_toElementFormType(self):
     544        """
     545        The form type is rendered as a hidden field with name FORM_TYPE.
     546        """
     547        form = data_form.Form('form', formNamespace='jabber:bot')
     548        element = form.toElement()
     549
     550        elements = list(element.elements())
     551        self.assertEqual(1, len(elements))
     552        formTypeField = elements[0]
     553        self.assertEqual('field', formTypeField.name)
     554        self.assertEqual(NS_X_DATA, formTypeField.uri)
     555        self.assertEqual('FORM_TYPE', formTypeField['var'])
     556        self.assertEqual('hidden', formTypeField['type'])
     557        self.assertEqual('jabber:bot', unicode(formTypeField.value))
     558
     559
     560    def test_toElementFields(self):
     561        """
     562        Fields are rendered as child elements, in order.
     563        """
     564        fields = [data_form.Field('fixed', value='Section 1'),
     565                  data_form.Field('text-single',
     566                                  var='botname',
     567                                  label='The name of your bot'),
     568                  data_form.Field('text-multi',
     569                                  var='description',
     570                                  label='Helpful description of your bot'),
     571                  data_form.Field('boolean',
     572                                  var='public',
     573                                  label='Public bot?',
     574                                  required=True)
     575                 ]
     576        form = data_form.Form('form', fields=fields)
     577        element = form.toElement()
     578
     579        elements = list(element.elements())
     580        self.assertEqual(4, len(elements))
     581        for field in elements:
     582            self.assertEqual('field', field.name)
     583            self.assertEqual(NS_X_DATA, field.uri)
     584
     585        # Check order
     586        self.assertEqual('fixed', elements[0]['type'])
     587        self.assertEqual('botname', elements[1]['var'])
     588        self.assertEqual('description', elements[2]['var'])
     589        self.assertEqual('public', elements[3]['var'])
     590
     591
    306592    def test_fromElement(self):
    307593        """
     
    348634
    349635        self.assertEquals(['instruction'], form.instructions)
     636
    350637
    351638    def test_fromElementInstructions2(self):
     
    378665        self.assertIn('field2', form.fields)
    379666        self.assertEquals('field2', form.fieldList[1].var)
     667
     668
     669    def test_fromElementFormType(self):
     670        """
     671        The form type is a hidden field named FORM_TYPE.
     672        """
     673        element = domish.Element((NS_X_DATA, 'x'))
     674        field = element.addElement('field')
     675        field['var'] = 'FORM_TYPE'
     676        field['type'] = 'hidden'
     677        field.addElement('value', content='myns')
     678        form = data_form.Form.fromElement(element)
     679
     680        self.assertNotIn('FORM_TYPE', form.fields)
     681        self.assertEqual('myns', form.formNamespace)
     682
     683    def test_fromElementFormTypeNotHidden(self):
     684        """
     685        A non-hidden field named FORM_TYPE does not set the form type.
     686        """
     687        element = domish.Element((NS_X_DATA, 'x'))
     688        field = element.addElement('field')
     689        field['var'] = 'FORM_TYPE'
     690        field.addElement('value', content='myns')
     691        form = data_form.Form.fromElement(element)
     692
     693        self.assertIn('FORM_TYPE', form.fields)
     694        self.assertIdentical(None, form.formNamespace)
     695
     696
     697    def test_fromElementChildOtherNamespace(self):
     698        """
     699        Child elements from another namespace are ignored.
     700        """
     701        element = domish.Element((NS_X_DATA, 'x'))
     702        element['type'] = 'result'
     703        field = element.addElement(('myns', 'field'))
     704        field['var'] = 'test'
     705        form = data_form.Form.fromElement(element)
     706
     707        self.assertEqual(0, len(form.fields))
     708
     709
     710    def test_repr(self):
     711        """
     712        The repr of a form should be equal to its initialization.
     713        """
     714        form = data_form.Form('form', title='title', instructions=['instr'],
     715                                      formNamespace='myns',
     716                                      fields=[data_form.Field('fixed',
     717                                                              value='test')])
     718        self.assertEqual("""Form(formType='form', title='title', """
     719                         """instructions=['instr'], formNamespace='myns', """
     720                         """fields=[Field(fieldType='fixed', """
     721                         """values=['test'])])""",
     722                         repr(form))
     723
     724
     725    def test_addField(self):
     726        """
     727        A field should occur in fieldList.
     728        """
     729        form = data_form.Form('result')
     730        field = data_form.Field('fixed', value='Section 1')
     731        form.addField(field)
     732        self.assertEqual([field], form.fieldList)
     733
     734
     735    def test_addFieldTwice(self):
     736        """
     737        Fields occur in fieldList in the order they were added.
     738        """
     739        form = data_form.Form('result')
     740        field1 = data_form.Field('fixed', value='Section 1')
     741        field2 = data_form.Field('fixed', value='Section 2')
     742        form.addField(field1)
     743        form.addField(field2)
     744        self.assertEqual([field1, field2], form.fieldList)
     745
     746
     747    def test_addFieldNotNamed(self):
     748        """
     749        A non-named field should not occur in fields.
     750        """
     751        form = data_form.Form('result')
     752        field = data_form.Field('fixed', value='Section 1')
     753        form.addField(field)
     754        self.assertEqual({}, form.fields)
     755
     756
     757    def test_addFieldNamed(self):
     758        """
     759        A named field should occur in fields.
     760        """
     761        form = data_form.Form('result')
     762        field = data_form.Field(var='test')
     763        form.addField(field)
     764        self.assertEqual({'test': field}, form.fields)
     765
     766
     767    def test_addFieldTwiceNamed(self):
     768        """
     769        A second named field should occur in fields.
     770        """
     771        form = data_form.Form('result')
     772        field1 = data_form.Field(var='test')
     773        field2 = data_form.Field(var='test2')
     774        form.addField(field2)
     775        form.addField(field1)
     776        self.assertEqual({'test': field1, 'test2': field2}, form.fields)
     777
     778
     779    def test_addFieldSameName(self):
     780        """
     781        A named field cannot occur twice.
     782        """
     783        form = data_form.Form('result')
     784        field1 = data_form.Field(var='test', value='value')
     785        field2 = data_form.Field(var='test', value='value2')
     786        form.addField(field1)
     787        self.assertRaises(data_form.Error, form.addField, field2)
     788
     789
     790    def test_getValues(self):
     791        """
     792        Each named field is represented in the values, keyed by name.
     793        """
     794        fields = [data_form.Field(var='botname', value='The Jabber Bot'),
     795                  data_form.Field('boolean', var='public', value=True),
     796                  data_form.Field('list-multi', var='features',
     797                                                values=['news', 'search'])]
     798        form = data_form.Form('submit', fields=fields)
     799        values = form.getValues()
     800        self.assertEqual({'botname': 'The Jabber Bot',
     801                          'public': True,
     802                          'features': ['news', 'search']},
     803                         values)
     804
     805
     806    def test_getValuesOneValueTypeMulti(self):
     807        """
     808        A single value for a multi-value field type is returned in a list.
     809        """
     810        fields = [data_form.Field('list-multi', var='features',
     811                                                values=['news'])]
     812        form = data_form.Form('submit', fields=fields)
     813        values = form.getValues()
     814        self.assertEqual({'features': ['news']}, values)
     815
     816
     817    def test_getValuesMultipleValuesNoType(self):
     818        """
     819        Multiple values for a field without type are returned in a list.
     820        """
     821        fields = [data_form.Field(None, var='features',
     822                                        values=['news', 'search'])]
     823        form = data_form.Form('submit', fields=fields)
     824        values = form.getValues()
     825        self.assertEqual({'features': ['news', 'search']}, values)
     826
     827
     828    def test_getValuesMultipleValuesTypeSingle(self):
     829        """
     830        Multiple values for a single-value field type returns the first value.
     831        """
     832        fields = [data_form.Field('text-single', var='features',
     833                                        values=['news', 'search'])]
     834        form = data_form.Form('submit', fields=fields)
     835        values = form.getValues()
     836        self.assertEqual({'features': 'news'}, values)
Note: See TracChangeset for help on using the changeset viewer.