[sylvain] r51050 - in Formulator/trunk: . tests

[email protected]
Newsgroups gmane.comp.web.zope.silva.cvs
Message-ID <[email protected]>
Author: sylvain
Date: Mon Aug 26 14:03:10 2013
New Revision: 51050

Added:
   Formulator/trunk/tests/test_form.py
   Formulator/trunk/tests/test_widgets.py
Removed:
   Formulator/trunk/tests/test_Form.py
Modified:
   Formulator/trunk/Widget.py
Log:
Fix the rendering of unicode values that was broken.



Modified: Formulator/trunk/Widget.py
==============================================================================
--- Formulator/trunk/Widget.py	(original)
+++ Formulator/trunk/Widget.py	Mon Aug 26 14:03:10 2013
@@ -3,9 +3,9 @@
 # See also LICENSE.txt
 import string
 import cgi
+import operator
 
 from DateTime import DateTime
-from DocumentTemplate.DT_Util import html_quote
 from Products.Formulator.DummyField import fields
 from Products.Formulator.helpers import is_sequence, id_value_re
 
@@ -105,10 +105,7 @@
     def render_view(self, field, value):
         """Renders this widget for public viewing.
         """
-        # default implementation
-        if value is None:
-            return ''
-        return cgi.escape(value)
+        return render_value(value)
 
 
 class TextWidget(Widget):
@@ -162,9 +159,8 @@
         return render_element("div", contents=contents, css_class=css_class)
 
     def render_view(self, field, value):
-        if value is None:
-            return ''
-        return cgi.escape(str(value))
+        return render_value(value)
+
 
 TextWidgetInstance = TextWidget()
 
@@ -265,19 +261,19 @@
               'css_class': css_class,
               'cols': width,
               'rows': height,
-              'contents': html_quote(value)}
+              'contents': cgi.escape(value)}
         if not extra or not id_value_re.search(extra):
             kw['id'] = field.generate_field_html_id(key)
         contents = render_element("textarea", **kw)
         return render_element("div", contents=contents, css_class=css_class)
 
     def render_view(self, field, value):
-        if value is None:
-            return ''
-        return cgi.escape(value)
+        return render_value(value)
+
 
 TextAreaWidgetInstance = TextAreaWidget()
 
+
 class LinesTextAreaWidget(TextAreaWidget):
     property_names = Widget.property_names +\
                      ['width', 'height', 'view_separator', 'extra']
@@ -306,9 +302,7 @@
         return TextAreaWidget.render(self, field, key, value, REQUEST)
 
     def render_view(self, field, value):
-        if value is None:
-            return ''
-        return cgi.escape(string.join(value, field.get_value('view_separator')))
+        return render_value(value, field.get_value('view_separator'))
 
     def render_hidden(self, field, key, value, REQUEST):
         if value is None:
@@ -471,8 +465,8 @@
                 item_text = item
                 item_value = item
             if value == item_value:
-                return cgi.escape(item_text)
-        raise KeyError, "Wrong item value [[%s]]" % (value,)
+                return render_value(item_text)
+        raise KeyError("Wrong item value [[%s]]" % (value,))
 
 class MultiItemsWidget(ItemsWidget):
     """A widget with a number of items that has multiple selectable
@@ -557,8 +551,9 @@
     def render_view(self, field, value):
         if value is None:
             return ''
-        return cgi.escape(string.join(self.render_items_view(field, value),
-                                      field.get_value('view_separator')))
+        return render_value(
+            self.render_items_view(field, value),
+            field.get_value('view_separator'))
 
     def render_hidden(self, field, key, value, REQUEST):
         if value is not None and not is_sequence(value):
@@ -1054,6 +1049,7 @@
 
 DateTimeWidgetInstance = DateTimeWidget()
 
+
 class LabelWidget(Widget):
     """Widget that is a label only. It simply returns its default value.
     """
@@ -1077,42 +1073,50 @@
     def render_view(self, field, value):
         return field.get_value('default')
 
+
 LabelWidgetInstance = LabelWidget()
 
-def render_tag(tag, **kw):
-    """Render the tag. Well, not all of it, as we may want to / it.
-    """
-    attr_list = []
+def render_tag(tag, css_class=None, extra=None, **attributes):
+    result = [tag]
 
     # special case handling for css_class
-    if kw.has_key('css_class'):
-        if kw['css_class'] != "":
-            attr_list.append('class="%s"' % kw['css_class'])
-        del kw['css_class']
-
-    # special case handling for extra 'raw' code
-    if kw.has_key('extra'):
-        extra = kw['extra'] # could be empty string but we don't care
-        del kw['extra']
-    else:
-        extra = ""
+    if css_class:
+        result.append('class="%s"' % css_class)
 
     # handle other attributes
-    for key, value in kw.items():
+    for key, value in sorted(attributes.items(), key=operator.itemgetter(0)):
         if value is None:
             if key == 'value':
                 value = ''
             else:
                 value = key
-        attr_list.append('%s="%s"' % (key, html_quote(value)))
+        result.append('%s="%s"' % (key, render_value(value)))
 
-    attr_str = string.join(attr_list, " ")
-    return "<%s %s %s" % (tag, attr_str, extra)
+    if extra:
+        result.append(extra)
+    return "<" + " ".join(result)
 
-def render_element(tag, **kw):
-    if kw.has_key('contents'):
-        contents = kw['contents']
-        del kw['contents']
-        return "%s>%s</%s>" % (apply(render_tag, (tag, ), kw), contents, tag)
-    else:
-        return apply(render_tag, (tag, ), kw) + " />"
+def render_element(tag, **kwargs):
+    """Render a tag.
+    """
+
+    if 'contents' in kwargs:
+        contents = kwargs.pop('contents')
+        return "%s>%s</%s>" % (render_tag(tag, **kwargs), contents, tag)
+    return render_tag(tag, **kwargs) + " />"
+
+def render_value(value, separator=None):
+    """Default helper to render a value, paying attention to unicode.
+    """
+    if value is None:
+        return u''
+    if separator is not None and isinstance(value, (list, tuple)):
+        if not isinstance(separator, unicode):
+            separator = unicode(separator, 'utf-8')
+        value = separator.join(value)
+    if not isinstance(value, unicode):
+        if isinstance(value, str):
+            value = value.decode('utf-8', 'replace')
+        else:
+            value = unicode(value)
+    return cgi.escape(value)

Added: Formulator/trunk/tests/test_form.py
==============================================================================
--- (empty file)
+++ Formulator/trunk/tests/test_form.py	Mon Aug 26 14:03:10 2013
@@ -0,0 +1,515 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2013  Infrae. All rights reserved.
+# See also LICENSE.txt
+""" random assembly testing some reported bugs.
+    This is _not_ a structured or even complete test suite.
+    Most tests test the "render" method of fields, thus they
+    maybe could be moved to a "test_widgets" test case partially
+"""
+
+import unittest, re
+from xml.dom.minidom import parseString
+
+from DateTime import DateTime
+from Products.PythonScripts.PythonScript import PythonScript
+
+from Products.Formulator.MethodField import Method
+from Products.Formulator.TALESField import TALESMethod
+
+from Products.Formulator.testing import FunctionalLayer, TestRequest
+
+
+class FormTestCase(unittest.TestCase):
+    layer = FunctionalLayer
+
+    def setUp(self):
+        self.layer.login('manager')
+        self.root = self.layer.get_application()
+        factory = self.root.manage_addProduct['Formulator']
+        factory.manage_add('form', 'Test Form')
+        self.form = self.root.form
+
+    def test_has_field(self):
+        """ test if has_field works, if one asks for a non-field attribute.
+            this has raised AttributeError "aq_explicit" in previous versions
+        """
+        self.assertFalse(self.form.has_field('title'))
+
+    def test_list_items(self):
+        self._test_list_items('ListField')
+
+    def test_multi_list_items(self):
+        self._test_list_items('MultiListField')
+
+    def _test_list_items(self, list_field_type):
+        """ test if a list of values returned by TALES (override) expressions
+        is interpreted properly.
+        If a TALES tab returns a sequence of items and some item is
+        actually a string of length 2 (e.g. "ok"), this previously
+        has lead to a item text of 'o' and a display value of 'k'
+        (as the this is actually a sequence of length 2 ...)
+         See http://sourceforge.net/mailarchive/forum.php?thread_id=1359918&forum_id=1702
+        """
+
+        self.form.manage_addField('list_field', 'Test List Field', list_field_type)
+
+        self.form.override_test = PythonScript('override_test')
+        self.form.override_test.write("return ['ok', 'no']\n")
+
+        list_field = self.form.list_field
+        list_field.values['items'] = [ ('ok', 'ok'), ('no', 'no') ]
+
+        list_field.values['first_item'] = 'on'
+
+        items1 = list_field.render()
+
+        # test TALES
+        list_field.tales['items'] = TALESMethod("python:['ok', 'no']")
+        items2 = list_field.render()
+
+        # test render
+        self.assertEquals(items1, items2)
+        # test render_view
+        self.assertEquals('ok', list_field.render_view('ok') )
+        # test validation ... fake request with a dictionary ...
+        list_field.validate({'field_list_field':'ok'})
+
+        # test override (most probably superfluous)
+        del list_field.tales['items']
+        list_field.overrides['items'] = Method('override_test')
+        items2 = list_field.render()
+
+        self.assertEquals(items1, items2)
+
+        # missing: if returning a list of int,
+        # rendering does work here, but validation fails.
+        # maybe it should fail, but on the other hand this is a FAQ on the list ...
+        del list_field.overrides['items']
+        # test when TALES returns a list of e.g. int
+        list_field.values['items'] = [ ('42', '42'), ('88', '88') ]
+
+        items1 = list_field.render()
+
+        list_field.tales['items'] = TALESMethod("python:[42, 88]")
+        items2 = list_field.render()
+
+        self.assertEquals(items1, items2)
+
+        list_field.validate({'field_list_field':'42'})
+
+    def test_items_is_sequence(self):
+        """ test that a multi list widget renders correctly,
+        even if the items consist out of a tuple.
+        this has bugged in some earlier version
+        """
+        # use a MultiCheckBoxField instead of a MultiListField just for variance
+        self.form.manage_addField('list_field', 'Test List Field', 'MultiCheckBoxField')
+
+        list_field = self.form.list_field
+        list_field.values['items'] = [ ('foo', 'foo'), ('bar', 'bar') ]
+
+        items1 = list_field.render( ('foo',) )
+
+        list_field.tales['items'] = TALESMethod("python:('foo', 'bar')")
+
+        self.assertEquals(('foo', 'bar'), list_field.get_value('items'))
+
+        items2 = list_field.render( ('foo',) )
+
+        # test render
+        self.assertEquals(items1, items2)
+        # test render_view
+        self.assertEquals("foo", list_field.render_view(('foo',)) )
+
+    def test_items_is_sequence_bis(self):
+        """ test that a multi list values widget renders correctly,
+            if the value from the request contains a list of non-ascii values
+        """
+        self.form.manage_addField('list_boxes', 'Test Checkboxes', 'MultiCheckBoxField')
+        self.encoding = "utf-8"
+        self.form.unicode_mode = 1
+        list_boxes = self.form.list_boxes
+        list_boxes.values['unicode'] = 1
+        list_boxes.values['items'] = \
+                 [ (u'\xe4', u'A uml'), (u'\xfc', u'U uml') ]
+        request = TestRequest()
+        request.form['key'] = ['\xc3\xa4','\xc3\xbc']
+        items = list_boxes._get_default(key='key', value=None,
+                                        REQUEST=request)
+        self.assertEquals([u'\xe4', u'\xfc'], items)
+
+        # same with latin-1 (we should not hardcode utf-8)
+        self.form.encoding = "latin-1"
+        request.form['key'] = ['\xe4','\xfc']
+        items = list_boxes._get_default(key='key', value=None,
+                                        REQUEST=request)
+        self.assertEquals([u'\xe4', u'\xfc'], items)
+
+    def test_lines_field_rendering(self):
+        """ line fields should both accept lists / tuples
+        of strings and single strings with whitespace.
+        If they would not accept the second case, render_from_request
+        would be broken.
+        """
+        self.form.manage_addField(
+            'lines_field', 'Test Lines Field', 'LinesField')
+
+        field = self.form.lines_field
+
+        request = TestRequest()
+        request.form['field_lines_field'] = 'Text'
+
+        rendered = field.render(REQUEST=request)
+
+        dom = parseString('<dummy>%s</dummy>' % rendered)
+        divs = [ child for child in dom.documentElement.childNodes \
+                     if child.nodeType == child.ELEMENT_NODE ]
+        self.assertEqual(len(divs), 1)
+        self.assertEqual(divs[0].nodeName, 'div')
+        textareas = [ child for child in divs[0].childNodes \
+                     if child.nodeType == child.ELEMENT_NODE ]
+        self.assertEqual(len(textareas), 1)
+        self.assertEqual(textareas[0].nodeName, 'textarea')
+        text = [ child for child in textareas[0].childNodes \
+                     if child.nodeType == child.TEXT_NODE ]
+
+        self.assertEquals('Text', ''.join(map(lambda n:n.nodeValue, text)))
+
+        field.values['hidden']='checked'
+        rendered = field.render(REQUEST=request)
+
+    def test_labels(self):
+        """ test that labels do not influence validation """
+        self.form.manage_addField(
+            'label_field', 'Test Label Field', 'LabelField')
+
+        self.form.label_field.overrides['default'] = "Some label"
+
+        self.form.manage_addField(
+            'int_field', 'Test integer field', 'IntegerField')
+
+        result = self.form.validate_all(
+            {'field_int_field': '3'})
+        self.assertEquals({'int_field': 3}, result)
+
+    def test_labels_with_direct_validation(self):
+        """ PloneFormMailer calls validate() directly on each field,
+        this used to give a KeyError as 'external_validator' wasn't
+        known for a label field.
+        """
+        self.form.manage_addField(
+            'label_field', 'Test Label Field', 'LabelField')
+        self.form['label_field'].validate(REQUEST=TestRequest())
+
+    def test_datetime_css_class_rendering(self):
+        # test that a bug is fixed, which causing the css_class value
+        # not to be rendered for DateTime fields
+
+        self.form.manage_addProduct['Formulator']\
+                 .manage_addField('date_time','Test Field','DateTimeField')
+        field = self.form.date_time
+
+        css_matcher = re.compile('class="([^"]*)"')
+
+        # initially no css class is set
+        self.assertEquals(0, len(css_matcher.findall(field.render())))
+
+        # edit the field, bypassing validation ...
+        field._edit({'css_class':'some_class'})
+
+        # now we should have five matches for the five subfields ...
+        css_matches = css_matcher.findall(field.render())
+        self.assertEquals(10, len(css_matches))
+        # ... and all have the given value:
+        for m in css_matches:
+            self.assertEquals('some_class',m)
+
+        # change the input style: the css needs to be
+        # propagated to the newly created subfields
+        current_style = field['input_style']
+        other_style = {'list':'text', 'text':'list'} [current_style]
+        field._edit({'input_style':other_style})
+
+        # still the css classes should remain the same
+        css_matches = css_matcher.findall(field.render())
+        self.assertEquals(7, len(css_matches))
+        for m in css_matches:
+            self.assertEquals('some_class',m)
+
+        # now just change to another value:
+        field._edit({'css_class':'other_class'})
+        css_matches = css_matcher.findall(field.render())
+        self.assertEquals(7, len(css_matches))
+        for m in css_matches:
+            self.assertEquals('other_class',m)
+
+        # and clear the css_class field:
+        field._edit({'css_class':''})
+        css_matches = css_matcher.findall(field.render())
+        self.assertEquals(0, len(css_matches))
+
+    def _helper_render_datetime(self,expected_values,rendered, type='hidden'):
+        # heper to check if the generated HTML from render or render_hidden
+        # meets the expectations
+        dom = parseString('<dummy>%s</dummy>' % rendered)
+        elements = [ child for child in dom.documentElement.childNodes \
+                     if child.nodeType == child.ELEMENT_NODE ]
+        if type != 'hidden':
+            # They are wrapped in divs if not hidden
+            self.assertEquals(len(elements), len(expected_values))
+            inputs = []
+            for element in elements:
+                inputs.extend([child for child in element.childNodes \
+                                   if child.nodeType == child.ELEMENT_NODE ])
+        else:
+            inputs = elements
+
+        self.assertEquals(len(expected_values.keys()), len(inputs))
+        values={}
+        for input in inputs:
+            self.assertEquals('input', input.nodeName)
+            self.assertEquals(type, input.getAttribute('type'))
+            self.assertFalse(input.childNodes)
+            values[input.getAttribute('name')] = input.getAttribute('value')
+        self.assertEquals(expected_values, values)
+
+    def _helper_render_hidden_list(self,expected_name, expected_values,
+                                   rendered):
+        # heper to check if the generated HTML from render_hidden
+        # meets the expectations
+        dom = parseString('<dummy>%s</dummy>' % rendered)
+        elements = [ child for child in dom.documentElement.childNodes \
+                     if child.nodeType == child.ELEMENT_NODE ]
+        self.assertEquals(len(expected_values), len(elements))
+        for child in elements:
+            self.assertEquals('input',child.nodeName)
+            self.assertEquals('hidden',child.getAttribute('type'))
+            self.assertEquals(expected_name,child.getAttribute('name'))
+            self.assertEquals(expected_values.pop(0),
+                              child.getAttribute('value'))
+            self.assertFalse(child.childNodes)
+
+
+    def test_render_hidden(self):
+        # test that rendering fields hidden does produce
+        # meaningful results; i.e. such which may still lead to successfull
+        # validation when submitting a form with hidden fields
+        # this has been broken for DateTimeFields, and fields
+        # which allowed multiple values
+        self.form.manage_addProduct['Formulator']\
+                 .manage_addField('date_time','Test Field','DateTimeField')
+        self.form.manage_addProduct['Formulator']\
+                  .manage_addField('multi_list','Test Field','MultiListField')
+        self.form.manage_addProduct['Formulator']\
+                 .manage_addField('check_boxes','Test Field','MultiCheckBoxField')
+        self.form.manage_addProduct['Formulator']\
+                  .manage_addField('lines','Test Field','LinesField')
+
+        self.form.date_time.values['default']=DateTime(1970,1,1,)
+        self.form.date_time.values['hidden']=1
+
+        expected_values = {
+            'subfield_date_time_year'  : '1970',
+            'subfield_date_time_month' : '01',
+            'subfield_date_time_day'   : '01',
+            'subfield_date_time_hour'  : '00',
+            'subfield_date_time_minute': '00',
+            }
+        self._helper_render_datetime(expected_values,
+                                     self.form.date_time.render())
+
+        self.form.date_time.values['date_only']=1
+        del expected_values['subfield_date_time_hour']
+        del expected_values['subfield_date_time_minute']
+        self._helper_render_datetime(expected_values,
+                                     self.form.date_time.render())
+
+        self.form.date_time.values['date_only']=0
+        self.form.date_time.values['ampm_time_style']=1
+        expected_values['subfield_date_time_hour']='12'
+        expected_values['subfield_date_time_minute']='00'
+        expected_values['subfield_date_time_ampm']='am'
+        self._helper_render_datetime(expected_values,
+                                     self.form.date_time.render())
+
+        self.form.multi_list.values['items'] = (('a','a'),('b','b'), ('c','c'))
+        self.form.multi_list.values['default'] = ['a','c']
+        self.form.multi_list.values['hidden'] = 1
+        self._helper_render_hidden_list('field_multi_list',['a','c'],
+                                        self.form.multi_list.render())
+
+        self.form.check_boxes.values['items'] = (('a','a'),('b','b'), ('c','c'))
+        self.form.check_boxes.values['default'] = ['a','c']
+        self.form.check_boxes.values['hidden'] = 1
+        self._helper_render_hidden_list('field_check_boxes',['a','c'],
+                                        self.form.check_boxes.render())
+
+
+        self.form.lines.values['default'] = ['a','c']
+        self.form.lines.values['hidden'] = 1
+        expect_str = 'a\nc'
+        # FIXME: a straight comparision fails ...
+        # minidom seems to barf on string linebreaks in attributes (?)
+        # instead ...
+        rendered = self.form.lines.render()
+        rendered = rendered.replace('\n','NEWLINE_HERE')
+        expect_str = expect_str.replace('\n','NEWLINE_HERE')
+        self._helper_render_hidden_list('field_lines',[expect_str],
+                                        rendered)
+
+    def test_render_view_items(self):
+        # test that the render_view is correct for fields
+        # for which the values internally handled by Formulator
+        # are different from the ones shown to the user
+        # (e.g. checkboxes, radio buttons, option-lists)
+
+        self.form.manage_addProduct['Formulator']\
+                  .manage_addField('single_list','Test Field','ListField')
+        self.form.manage_addProduct['Formulator']\
+                  .manage_addField('multi_list','Test Field','MultiListField')
+        self.form.manage_addProduct['Formulator']\
+                 .manage_addField('check_boxes','Test Field',
+                                  'MultiCheckBoxField')
+        self.form.manage_addProduct['Formulator']\
+                 .manage_addField('radio','Test Field','RadioField')
+
+        for field in self.form.single_list, self.form.radio:
+            field.values['items'] = [ ('Alpha','a'),
+                                      ('Beta','b'),
+                                      ('Gamma','c'), ]
+            self.assertEquals('Gamma',field.render_view('c'),msg=field.id)
+
+
+        for field in self.form.multi_list, self.form.check_boxes:
+            field.values['items'] = [ ('Alpha','a'),
+                                      ('Beta','b'),
+                                      ('Gamma','c'), ]
+
+            field.values['view_separator'] = '|||'
+            self.assertEquals('Gamma',field.render_view(['c']))
+            self.assertEquals('|||'.join(('Alpha','Gamma')),
+                              field.render_view(['a','c']))
+            self.assertEquals('', field.render_view([]))
+
+    def test_default_to_now_does_not_overwrite_request_values(self):
+        self.form.manage_addField('date_field','Test DateTime Field','DateTimeField')
+        date_field = self.form.date_field
+
+        date_field.values['default_now'] = 1
+        date_field.values['default'] = DateTime('1971/01/01')
+        date_field.values['date_only'] = 1 # for less typing in test only ...
+
+        expected_values = \
+                       {'subfield_date_field_year':'1970',
+                        'subfield_date_field_month':'01',
+                        'subfield_date_field_day' : '01'}
+
+        request = TestRequest(form=expected_values)
+        rendered = date_field.render_from_request(request)
+        self._helper_render_datetime(expected_values, rendered, type='text')
+
+        # as we are already here, check yet another thing:
+        # test that default is honored if no value given
+        expected_values['subfield_date_field_year'] = '1971'
+        rendered = date_field.render_from_request(TestRequest())
+        self._helper_render_datetime(expected_values, rendered, type='text')
+
+    def test_checkbox_default_overwrites_submitted_values(self):
+        self.form.manage_addField('checkbox_field','Test Checkbox','CheckBoxField')
+        checkbox_field = self.form.checkbox_field
+
+        checkbox_field.values['default'] = 1
+
+        rendered = checkbox_field.render()
+        self.assert_(-1 != rendered.find('checked="checked"'))
+
+        request = TestRequest()
+        rendered = checkbox_field.render_from_request(request)
+        self.assert_(-1 != rendered.find('checked="checked"'))
+
+        request.form['formulator_submission']='1'
+        rendered = checkbox_field.render_from_request(request)
+        self.assertEquals(-1, rendered.find('checked="checked"'))
+
+    def test_edit_listitem(self):
+        """ if eding a list item via ZMI (or xml rpc) in unicode mode
+        this has blown because some lists of strings have
+        not been converted properly
+        """
+        self.form.unicode_mode = 1
+        self.form.manage_addField('list_field','Test Listfield','ListField')
+        self.form.manage_addField('lines_field','Test Linesfield','LinesField')
+        list_field = self.form.list_field
+        lines_field = self.form.lines_field
+        # just to make sure
+        self.assert_(list_field.get_unicode_mode())
+
+        # the list field has the most complicated setting:
+        # a list of 2-tuples for the 'items'
+        request = TestRequest(form={
+                'field_title' : 'Title\xc3\xbc' ,
+                'field_default' : 'item\xc3\xbc',
+                'field_items': 'item\xc3\xbc | item_ue\nitem2 | item2',
+                'field_size': '7',
+                })
+        list_field.manage_edit(request)
+        self.assertEquals(u'item\xfc',
+                          list_field.get_value('default') )
+        expected_items = [ (u'item\xfc',u'item_ue'), ('item2','item2') ]
+        self.assertEquals(expected_items,
+                          list_field.get_value('items') )
+
+        self.assertEquals(7, list_field.get_value('size'))
+
+        # the lines field has a plain list of string as 'default'
+        request = TestRequest(form={
+                'field_title' : 'Title\xc3\xbc' ,
+                'field_default' : 'item\xc3\xbc\nitem2',
+                'field_width': '40',
+                'field_height': '5',
+                'field_view_separator': 'sep \xc3\xbc',
+                })
+        lines_field.manage_edit(request)
+        self.assertEquals(u'Title\xfc',
+                          lines_field.get_value('title') )
+        self.assertEquals([u'item\xfc', u'item2'],
+                          lines_field.get_value('default') )
+
+    def test_tales_none(self):
+        # test that a TALES default of None is rendered
+        # as the empty string in the field's value attribute
+        # and not as "value"
+        self.form.manage_addField('text','Text Field','StringField')
+        text = self.form.text
+        text.tales['default'] = TALESMethod('nothing')
+        self.assertEquals(1, text.render().count('value=""') )
+
+    def test_add_unicode_form(self):
+        # test bugfix when adding a form with a non-ascii title
+        # and the unicode flag set
+        self.root.manage_addProduct['Formulator'] \
+                 .manage_add('form2', 'Test Form b\xef\xbf\xbdr', unicode_mode=1)
+        form2 = self.root.form2
+        self.assertEquals(1, form2.get_unicode_mode())
+        self.assertEquals( type(u' '), type(form2.title))
+        self.assertEquals( u'Test Form b\ufffdr', form2.title)
+
+    def test_add_unicode_field(self):
+        # test bugfix when adding a field with a non-ascii title
+        # to a form with the unicode flag set
+        self.root.manage_addProduct['Formulator'] \
+                 .manage_add('form2', 'Test Form b\xef\xbf\xbdr', unicode_mode=1)
+        form2 = self.root.form2
+        self.assertEquals(1, form2.get_unicode_mode())
+
+        form2.manage_addField('testfield', 'Test field b\xef\xbf\xbdr', \
+                              'StringField')
+        self.assertEquals(type(u' '), type(form2.testfield.title()))
+        self.assertEquals(u'Test field b\ufffdr', form2.testfield.title())
+        self.assertEquals(u'Test field b\ufffdr', form2.testfield.get_value('title'))
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(FormTestCase))
+    return suite

Added: Formulator/trunk/tests/test_widgets.py
==============================================================================
--- (empty file)
+++ Formulator/trunk/tests/test_widgets.py	Mon Aug 26 14:03:10 2013
@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2013  Infrae. All rights reserved.
+# See also LICENSE.txt
+
+import unittest
+
+from Products.Formulator.testing import FunctionalLayer
+
+
+class WidgetTestCase(unittest.TestCase):
+    layer = FunctionalLayer
+
+    def setUp(self):
+        self.layer.login('manager')
+        self.root = self.layer.get_application()
+        factory = self.root.manage_addProduct['Formulator']
+        factory.manage_add('form', 'Test Form')
+
+    def test_integer(self):
+        """Test render an integer value.
+        """
+        self.root.form.manage_addField('age_field', 'Age', 'IntegerField')
+        self.assertEqual(
+            self.root.form.age_field.render(value=42),
+            u'<div><input id="field-age-field" name="field_age_field" size="20" type="text" value="42" /></div>')
+        self.assertEqual(
+            self.root.form.age_field.render_view(value=42),
+            u'42')
+
+    def test_string_empty(self):
+        """Create a regular TextField and render an empty value.
+        """
+        self.root.form.manage_addField('text_field', 'Name', 'StringField')
+        self.assertEqual(
+            self.root.form.text_field.render(value=None),
+            u'<div><input id="field-text-field" name="field_text_field" size="20" type="text" value="" /></div>')
+        self.assertEqual(
+            self.root.form.text_field.render_view(value=None),
+            u'')
+
+    def test_string_escape_html(self):
+        """Create a regular TextField and render an unicode value
+        containing HTML entities.
+        """
+        self.root.form.manage_addField('text_field', 'Name', 'StringField')
+        self.assertEqual(
+            self.root.form.text_field.render(value=u"<élèves />"),
+            u'<div><input id="field-text-field" name="field_text_field" size="20" type="text" value="&lt;élèves /&gt;" /></div>')
+        self.assertEqual(
+            self.root.form.text_field.render_view(value=u"<élèves />"),
+            u'&lt;élèves /&gt;')
+
+    def test_string_unicode(self):
+        """Create a regular TextField and render an unicode value.
+        """
+        self.root.form.manage_addField('text_field', 'Name', 'StringField')
+        self.assertEqual(
+            self.root.form.text_field.render(value=u"élèves du primaire"),
+            u'<div><input id="field-text-field" name="field_text_field" size="20" type="text" value="élèves du primaire" /></div>')
+        self.assertEqual(
+            self.root.form.text_field.render_view(value=u"élèves du primaire"),
+            u'élèves du primaire')
+
+    def test_textarea_escape_html(self):
+        """Create a regular TextAreaField and render an unicode value
+        containing HTML entities.
+        """
+        self.root.form.manage_addField('life_field', 'Life', 'TextAreaField')
+        self.assertEqual(
+            self.root.form.life_field.render(value=u"<b>élèves</b>"),
+            u'<div><textarea cols="40" id="field-life-field" name="field_life_field" rows="5">&lt;b&gt;élèves&lt;/b&gt;</textarea></div>')
+        self.assertEqual(
+            self.root.form.life_field.render_view(value=u"<b>élèves</b>"),
+            u'&lt;b&gt;élèves&lt;/b&gt;')
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(WidgetTestCase))
+    return suite
_______________________________________________
silva-cvs mailing list
[email protected]
https://lists.infrae.com/mailman/listinfo/silva-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.