Skip to content

Commit

Permalink
Rolled back the famous Date(time)Widget fix (see revison 68818 for de…
Browse files Browse the repository at this point in the history
…tails).

Added Date(time)I18nWidget instead.
  • Loading branch information
Dmitry Vasiliev committed Jul 1, 2006
1 parent 0776a31 commit c843b1b
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 39 deletions.
78 changes: 78 additions & 0 deletions browser/__init__.py
@@ -0,0 +1,78 @@
##############################################################################
#
# Copyright (c) 2004 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Browser widgets
$Id$
"""
__docformat__ = 'restructuredtext'

from zope.app.form.browser.widget import BrowserWidget, DisplayWidget
from zope.app.form.browser.widget import UnicodeDisplayWidget

from zope.app.form.browser.textwidgets import TextWidget, BytesWidget
from zope.app.form.browser.textwidgets import TextAreaWidget, BytesAreaWidget
from zope.app.form.browser.textwidgets import PasswordWidget, FileWidget
from zope.app.form.browser.textwidgets import ASCIIWidget, ASCIIAreaWidget
from zope.app.form.browser.textwidgets import IntWidget, FloatWidget
from zope.app.form.browser.textwidgets import DatetimeWidget, DateWidget
from zope.app.form.browser.textwidgets import DatetimeI18nWidget
from zope.app.form.browser.textwidgets import DateI18nWidget
from zope.app.form.browser.textwidgets import DatetimeDisplayWidget
from zope.app.form.browser.textwidgets import DateDisplayWidget
from zope.app.form.browser.textwidgets import BytesDisplayWidget
from zope.app.form.browser.textwidgets import ASCIIDisplayWidget
from zope.app.form.browser.textwidgets import URIDisplayWidget

# Widgets for boolean fields
from zope.app.form.browser.boolwidgets import CheckBoxWidget
from zope.app.form.browser.boolwidgets import BooleanRadioWidget
from zope.app.form.browser.boolwidgets import BooleanSelectWidget
from zope.app.form.browser.boolwidgets import BooleanDropdownWidget

# Choice and Sequence Display Widgets
from zope.app.form.browser.itemswidgets import ItemDisplayWidget
from zope.app.form.browser.itemswidgets import ItemsMultiDisplayWidget
from zope.app.form.browser.itemswidgets import SetDisplayWidget
from zope.app.form.browser.itemswidgets import ListDisplayWidget

# Widgets for fields with vocabularies.
# Note that these are only dispatchers for the widgets below.
from zope.app.form.browser.itemswidgets import ChoiceDisplayWidget
from zope.app.form.browser.itemswidgets import ChoiceInputWidget
from zope.app.form.browser.itemswidgets import CollectionDisplayWidget
from zope.app.form.browser.itemswidgets import CollectionInputWidget
from zope.app.form.browser.itemswidgets import ChoiceCollectionDisplayWidget
from zope.app.form.browser.itemswidgets import ChoiceCollectionInputWidget

# Widgets that let you choose a single item from a list
# These widgets are multi-views on (field, vocabulary)
from zope.app.form.browser.itemswidgets import SelectWidget
from zope.app.form.browser.itemswidgets import DropdownWidget
from zope.app.form.browser.itemswidgets import RadioWidget

# Widgets that let you choose several items from a list
# These widgets are multi-views on (field, vocabulary)
from zope.app.form.browser.itemswidgets import MultiSelectWidget
from zope.app.form.browser.itemswidgets import MultiSelectSetWidget
from zope.app.form.browser.itemswidgets import MultiCheckBoxWidget
from zope.app.form.browser.itemswidgets import OrderedMultiSelectWidget

# Widgets that let you enter several items in a sequence
# These widgets are multi-views on (sequence type, value type)
from zope.app.form.browser.sequencewidget import SequenceWidget
from zope.app.form.browser.sequencewidget import TupleSequenceWidget
from zope.app.form.browser.sequencewidget import ListSequenceWidget
from zope.app.form.browser.sequencewidget import SequenceDisplayWidget

from zope.app.form.browser.objectwidget import ObjectWidget
43 changes: 19 additions & 24 deletions browser/ftests/test_datetimewidget.py
Expand Up @@ -22,7 +22,7 @@
from datetime import datetime

import zope.security.checker
from zope.datetime import tzinfo
from zope.datetime import parseDatetimetz, tzinfo
from zope.interface import Interface, implements
from zope.schema import Datetime, Choice
from zope.traversing.api import traverse
Expand All @@ -39,22 +39,22 @@ class IDatetimeTest(Interface):
d3 = Choice(
required=False,
values=(
datetime(2003, 9, 15),
datetime(2003, 10, 15)),
missing_value=datetime(2000, 1, 1))
datetime(2003, 9, 15, tzinfo=tzinfo(0)),
datetime(2003, 10, 15, tzinfo=tzinfo(0))),
missing_value=datetime(2000, 1, 1, tzinfo=tzinfo(0)))

d1 = Datetime(
required=True,
min=datetime(2003, 1, 1),
max=datetime(2020, 12, 31))
min=datetime(2003, 1, 1, tzinfo=tzinfo(0)),
max=datetime(2020, 12, 31, tzinfo=tzinfo(0)))

class DatetimeTest(Persistent):

implements(IDatetimeTest)

def __init__(self):
self.d1 = datetime(2003, 4, 6)
self.d2 = datetime(2003, 8, 6)
self.d1 = datetime(2003, 4, 6, tzinfo=tzinfo(0))
self.d2 = datetime(2003, 8, 6, tzinfo=tzinfo(0))
self.d3 = None

class Test(BrowserTestCase):
Expand All @@ -80,12 +80,7 @@ def getDateForField(self, field, source):
m = re.search(pattern, source, re.DOTALL)
if m is None:
return None

request = self.makeRequest(env={"HTTP_ACCEPT_LANGUAGE": "ru"})

formatter = request.locale.dates.getFormatter("dateTime")

return formatter.parse(m.group(1))
return parseDatetimetz(m.group(1))

def test_display_editform(self):
self.getRootFolder()['test'] = DatetimeTest()
Expand All @@ -112,19 +107,19 @@ def test_submit_editform(self):
# submit edit view
response = self.publish('/test/edit.html', form={
'UPDATE_SUBMIT' : '',
'field.d1' : u'Feb 1, 2003 12:00:00 AM',
'field.d2' : u'Feb 2, 2003 12:00:00 AM',
'field.d3' : u'2003-10-15 00:00:00' },
'field.d1' : u'2003-02-01 00:00:00+00:00',
'field.d2' : u'2003-02-02 00:00:00+00:00',
'field.d3' : u'2003-10-15 00:00:00+00:00' },
env={"HTTP_ACCEPT_LANGUAGE": "en"})
self.assertEqual(response.getStatus(), 200)
self.assert_(updatedMsgExists(response.getBody()))

# check new values in object
object = traverse(self.getRootFolder(), 'test')

self.assertEqual(object.d1, datetime(2003, 2, 1))
self.assertEqual(object.d2, datetime(2003, 2, 2))
self.assertEqual(object.d3, datetime(2003, 10, 15))
self.assertEqual(object.d1, datetime(2003, 2, 1, tzinfo=tzinfo(0)))
self.assertEqual(object.d2, datetime(2003, 2, 2, tzinfo=tzinfo(0)))
self.assertEqual(object.d3, datetime(2003, 10, 15, tzinfo=tzinfo(0)))


def test_missing_value(self):
Expand All @@ -143,7 +138,7 @@ def test_missing_value(self):
object = traverse(self.getRootFolder(), 'test')
self.assert_(object.d2 is None) # default missing_value for dates
# 2000-1-1 is missing_value for d3
self.assertEqual(object.d3, datetime(2000, 1, 1))
self.assertEqual(object.d3, datetime(2000, 1, 1, tzinfo=tzinfo(0)))


def test_required_validation(self):
Expand Down Expand Up @@ -171,7 +166,7 @@ def test_invalid_value(self):
# submit a value for d3 that isn't allowed
response = self.publish('/test/edit.html', form={
'UPDATE_SUBMIT' : '',
'field.d3' : u'Feb 1, 2003 12:00:00 AM'})
'field.d3' : u'2003-02-01 12:00:00+00:00'})
self.assertEqual(response.getStatus(), 200)
self.assert_(invalidValueErrorExists('d3', response.getBody()))

Expand All @@ -183,7 +178,7 @@ def test_min_max_validation(self):
# submit value for d1 that is too low
response = self.publish('/test/edit.html', form={
'UPDATE_SUBMIT' : '',
'field.d1' : u'Dec 31, 2002 12:00:00 AM'},
'field.d1' : u'2002-12-31 12:00:00+00:00'},
env={"HTTP_ACCEPT_LANGUAGE": "en"})
self.assertEqual(response.getStatus(), 200)
self.assert_(validationErrorExists('d1', 'Value is too small',
Expand All @@ -192,7 +187,7 @@ def test_min_max_validation(self):
# submit value for i1 that is too high
response = self.publish('/test/edit.html', form={
'UPDATE_SUBMIT' : '',
'field.d1' : u'Dec 1, 2021 12:00:00 AM'},
'field.d1' : u'2021-12-01 12:00:00+00:00'},
env={"HTTP_ACCEPT_LANGUAGE": "en"})
self.assertEqual(response.getStatus(), 200)
self.assert_(validationErrorExists('d1', 'Value is too big',
Expand Down
49 changes: 43 additions & 6 deletions browser/tests/test_datetimewidget.py
Expand Up @@ -19,12 +19,13 @@
import unittest, doctest

from zope.schema import Datetime
from zope.datetime import tzinfo
from zope.datetime import parseDatetimetz, tzinfo
from zope.interface.verify import verifyClass

from zope.app.form.browser.tests.test_browserwidget import SimpleInputWidgetTest
from zope.app.form.interfaces import IInputWidget
from zope.app.form.browser import DatetimeWidget
from zope.app.form.browser import DatetimeI18nWidget
from zope.app.form.interfaces import ConversionError, WidgetInputError


Expand All @@ -38,40 +39,75 @@ class DatetimeWidgetTest(SimpleInputWidgetTest):
_FieldFactory = Datetime
_WidgetFactory = DatetimeWidget

def testRender(self):
super(DatetimeWidgetTest, self).testRender(
datetime.datetime(2004, 3, 26, 12, 58, 59),
('type="text"', 'id="field.foo"', 'name="field.foo"',
'value="2004-03-26 12:58:59"'))

def test_hasInput(self):
del self._widget.request.form['field.foo']
self.failIf(self._widget.hasInput())
# widget has input, even if input is an empty string
self._widget.request.form['field.foo'] = u''
self.failUnless(self._widget.hasInput())
self._widget.request.form['field.foo'] = u'2003-03-26 12:00:00'
self.failUnless(self._widget.hasInput())

def test_getInputValue(self,
value=u'2004-03-26 12:58:59',
check_value=parseDatetimetz('2004-03-26 12:58:59')):
self._widget.request.form['field.foo'] = u''
self.assertRaises(WidgetInputError, self._widget.getInputValue)
self._widget.request.form['field.foo'] = value
self.assertEquals(self._widget.getInputValue(), check_value)
self._widget.request.form['field.foo'] = u'abc'
self.assertRaises(ConversionError, self._widget.getInputValue)

class DatetimeI18nWidgetTest(SimpleInputWidgetTest):
"""Documents and tests the i18n datetime widget.
>>> verifyClass(IInputWidget, DatetimeI18nWidget)
True
"""

_FieldFactory = Datetime
_WidgetFactory = DatetimeI18nWidget

def testDefaultDisplayStyle(self):
self.failIf(self._widget.displayStyle)

def testRender(self):
super(DatetimeWidgetTest, self).testRender(
super(DatetimeI18nWidgetTest, self).testRender(
datetime.datetime(2004, 3, 26, 12, 58, 59),
('type="text"', 'id="field.foo"', 'name="field.foo"',
'value="26.03.2004 12:58:59"'))

def testRenderShort(self):
self._widget.displayStyle = "short"
super(DatetimeWidgetTest, self).testRender(
super(DatetimeI18nWidgetTest, self).testRender(
datetime.datetime(2004, 3, 26, 12, 58, 59),
('type="text"', 'id="field.foo"', 'name="field.foo"',
'value="26.03.04 12:58"'))

def testRenderMedium(self):
self._widget.displayStyle = "medium"
super(DatetimeWidgetTest, self).testRender(
super(DatetimeI18nWidgetTest, self).testRender(
datetime.datetime(2004, 3, 26, 12, 58, 59),
('type="text"', 'id="field.foo"', 'name="field.foo"',
'value="26.03.2004 12:58:59"'))

def testRenderLong(self):
self._widget.displayStyle = "long"
super(DatetimeWidgetTest, self).testRender(
super(DatetimeI18nWidgetTest, self).testRender(
datetime.datetime(2004, 3, 26, 12, 58, 59),
('type="text"', 'id="field.foo"', 'name="field.foo"',
u'value="26 \u041c\u0430\u0440\u0442 2004 \u0433.'
u' 12:58:59 +000"'))

def testRenderFull(self):
self._widget.displayStyle = "full"
super(DatetimeWidgetTest, self).testRender(
super(DatetimeI18nWidgetTest, self).testRender(
datetime.datetime(2004, 3, 26, 12, 58, 59),
('type="text"', 'id="field.foo"', 'name="field.foo"',
u'value="26 \u041c\u0430\u0440\u0442 2004 \u0433.'
Expand Down Expand Up @@ -132,6 +168,7 @@ def test_getFullInputValue(self):
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(DatetimeWidgetTest),
unittest.makeSuite(DatetimeI18nWidgetTest),
doctest.DocTestSuite(),
))

Expand Down
46 changes: 41 additions & 5 deletions browser/tests/test_datewidget.py
Expand Up @@ -25,6 +25,7 @@
from zope.app.form.browser.tests.test_browserwidget import SimpleInputWidgetTest
from zope.app.form.interfaces import IInputWidget
from zope.app.form.browser import DateWidget
from zope.app.form.browser import DateI18nWidget
from zope.app.form.interfaces import ConversionError, WidgetInputError


Expand All @@ -38,39 +39,73 @@ class DateWidgetTest(SimpleInputWidgetTest):
_FieldFactory = Date
_WidgetFactory = DateWidget

def testRender(self):
super(DateWidgetTest, self).testRender(
datetime.date(2003, 3, 26),
('type="text"', 'id="field.foo"', 'name="field.foo"',
'value="2003-03-26"'))

def test_hasInput(self):
del self._widget.request.form['field.foo']
self.failIf(self._widget.hasInput())
self._widget.request.form['field.foo'] = u''
self.failUnless(self._widget.hasInput())
self._widget.request.form['field.foo'] = u'2003-03-26'
self.failUnless(self._widget.hasInput())

def test_getInputValue(self,
value=u'2004-03-26',
check_value=datetime.date(2004, 3, 26)):
self._widget.request.form['field.foo'] = u''
self.assertRaises(WidgetInputError, self._widget.getInputValue)
self._widget.request.form['field.foo'] = value
self.assertEquals(self._widget.getInputValue(), check_value)
self._widget.request.form['field.foo'] = u'abc'
self.assertRaises(ConversionError, self._widget.getInputValue)

class DateI18nWidgetTest(SimpleInputWidgetTest):
"""Documents and tests the i18n date widget.
>>> verifyClass(IInputWidget, DateI18nWidget)
True
"""

_FieldFactory = Date
_WidgetFactory = DateI18nWidget

def testDefaultDisplayStyle(self):
self.failIf(self._widget.displayStyle)

def testRender(self):
super(DateWidgetTest, self).testRender(
super(DateI18nWidgetTest, self).testRender(
datetime.date(2003, 3, 26),
('type="text"', 'id="field.foo"', 'name="field.foo"',
'value="26.03.2003"'))

def testRenderShort(self):
self._widget.displayStyle = "short"
super(DateWidgetTest, self).testRender(
super(DateI18nWidgetTest, self).testRender(
datetime.datetime(2004, 3, 26, 12, 58, 59),
('type="text"', 'id="field.foo"', 'name="field.foo"',
'value="26.03.04"'))

def testRenderMedium(self):
self._widget.displayStyle = "medium"
super(DateWidgetTest, self).testRender(
super(DateI18nWidgetTest, self).testRender(
datetime.datetime(2004, 3, 26, 12, 58, 59),
('type="text"', 'id="field.foo"', 'name="field.foo"',
'value="26.03.2004"'))

def testRenderLong(self):
self._widget.displayStyle = "long"
super(DateWidgetTest, self).testRender(
super(DateI18nWidgetTest, self).testRender(
datetime.datetime(2004, 3, 26, 12, 58, 59),
('type="text"', 'id="field.foo"', 'name="field.foo"',
u'value="26 \u041c\u0430\u0440\u0442 2004 \u0433."'))

def testRenderFull(self):
self._widget.displayStyle = "full"
super(DateWidgetTest, self).testRender(
super(DateI18nWidgetTest, self).testRender(
datetime.datetime(2004, 3, 26, 12, 58, 59),
('type="text"', 'id="field.foo"', 'name="field.foo"',
u'value="26 \u041c\u0430\u0440\u0442 2004 \u0433."'))
Expand Down Expand Up @@ -117,6 +152,7 @@ def test_getFullInputValue(self):
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(DateWidgetTest),
unittest.makeSuite(DateI18nWidgetTest),
doctest.DocTestSuite(),
))

Expand Down

0 comments on commit c843b1b

Please sign in to comment.