[Zope3-checkins] SVN: Zope3/trunk/ Merged revision 68937 from the
3.3 branch:
Dmitry Vasiliev
dima at hlabs.spb.ru
Sat Jul 1 13:37:15 EDT 2006
Log message for revision 68938:
Merged revision 68937 from the 3.3 branch:
Rolled back the famous Date(time)Widget fix (see revison 68818 for details).
Added Date(time)I18nWidget instead.
Changed:
U Zope3/trunk/doc/CHANGES.txt
U Zope3/trunk/src/zope/app/form/browser/__init__.py
U Zope3/trunk/src/zope/app/form/browser/ftests/test_datetimewidget.py
U Zope3/trunk/src/zope/app/form/browser/tests/test_datetimewidget.py
U Zope3/trunk/src/zope/app/form/browser/tests/test_datewidget.py
U Zope3/trunk/src/zope/app/form/browser/textwidgets.py
U Zope3/trunk/src/zope/formlib/form.txt
-=-
Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt 2006-07-01 17:18:56 UTC (rev 68937)
+++ Zope3/trunk/doc/CHANGES.txt 2006-07-01 17:37:13 UTC (rev 68938)
@@ -17,8 +17,9 @@
Bug fixes
- Fixed issue 525: DateWidget ru-format.
- If you plan to use DatetimeWidget with timezone information take a look
- at the note in the DatetimeWidget docstring;
+ Added new Date(time)I18nWidget. Note: if you plan to use
+ DatetimeI18nWidget with timezone information take a look
+ at the note in the DatetimeI18nWidget docstring;
- Fixed issue 531: Spurious i18n deprecation warnings;
Modified: Zope3/trunk/src/zope/app/form/browser/__init__.py
===================================================================
--- Zope3/trunk/src/zope/app/form/browser/__init__.py 2006-07-01 17:18:56 UTC (rev 68937)
+++ Zope3/trunk/src/zope/app/form/browser/__init__.py 2006-07-01 17:37:13 UTC (rev 68938)
@@ -26,6 +26,8 @@
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
Modified: Zope3/trunk/src/zope/app/form/browser/ftests/test_datetimewidget.py
===================================================================
--- Zope3/trunk/src/zope/app/form/browser/ftests/test_datetimewidget.py 2006-07-01 17:18:56 UTC (rev 68937)
+++ Zope3/trunk/src/zope/app/form/browser/ftests/test_datetimewidget.py 2006-07-01 17:37:13 UTC (rev 68938)
@@ -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
@@ -39,22 +39,22 @@
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):
@@ -80,13 +80,8 @@
m = re.search(pattern, source, re.DOTALL)
if m is None:
return None
+ return parseDatetimetz(m.group(1))
- request = self.makeRequest(env={"HTTP_ACCEPT_LANGUAGE": "ru"})
-
- formatter = request.locale.dates.getFormatter("dateTime")
-
- return formatter.parse(m.group(1))
-
def test_display_editform(self):
self.getRootFolder()['test'] = DatetimeTest()
transaction.commit()
@@ -112,9 +107,9 @@
# 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()))
@@ -122,9 +117,9 @@
# 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):
@@ -143,7 +138,7 @@
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):
@@ -171,7 +166,7 @@
# 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()))
@@ -183,7 +178,7 @@
# 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',
@@ -192,7 +187,7 @@
# 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',
Modified: Zope3/trunk/src/zope/app/form/browser/tests/test_datetimewidget.py
===================================================================
--- Zope3/trunk/src/zope/app/form/browser/tests/test_datetimewidget.py 2006-07-01 17:18:56 UTC (rev 68937)
+++ Zope3/trunk/src/zope/app/form/browser/tests/test_datetimewidget.py 2006-07-01 17:37:13 UTC (rev 68938)
@@ -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
@@ -38,32 +39,67 @@
_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.'
@@ -71,7 +107,7 @@
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.'
@@ -132,6 +168,7 @@
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(DatetimeWidgetTest),
+ unittest.makeSuite(DatetimeI18nWidgetTest),
doctest.DocTestSuite(),
))
Modified: Zope3/trunk/src/zope/app/form/browser/tests/test_datewidget.py
===================================================================
--- Zope3/trunk/src/zope/app/form/browser/tests/test_datewidget.py 2006-07-01 17:18:56 UTC (rev 68937)
+++ Zope3/trunk/src/zope/app/form/browser/tests/test_datewidget.py 2006-07-01 17:37:13 UTC (rev 68938)
@@ -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
@@ -38,39 +39,73 @@
_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."'))
@@ -117,6 +152,7 @@
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(DateWidgetTest),
+ unittest.makeSuite(DateI18nWidgetTest),
doctest.DocTestSuite(),
))
Modified: Zope3/trunk/src/zope/app/form/browser/textwidgets.py
===================================================================
--- Zope3/trunk/src/zope/app/form/browser/textwidgets.py 2006-07-01 17:18:56 UTC (rev 68937)
+++ Zope3/trunk/src/zope/app/form/browser/textwidgets.py 2006-07-01 17:37:13 UTC (rev 68938)
@@ -19,6 +19,8 @@
from xml.sax import saxutils
from zope.interface import implements
+from zope.datetime import parseDatetimetz
+from zope.datetime import DateTimeError
from zope.i18n.format import DateTimeParseError
from zope.app.form.interfaces import IInputWidget, ConversionError
@@ -483,9 +485,37 @@
except ValueError, v:
raise ConversionError(_("Invalid floating point data"), v)
-class DateWidget(TextWidget):
+class DatetimeWidget(TextWidget):
+ """Datetime entry widget."""
+
+ displayWidth = 20
+
+ def _toFieldValue(self, input):
+ if input == self._missing:
+ return self.context.missing_value
+ else:
+ try:
+ # TODO: Currently datetimes return in local (server)
+ # time zone if no time zone information was given.
+ # Maybe offset-naive datetimes should be returned in
+ # this case? (DV)
+ return parseDatetimetz(input)
+ except (DateTimeError, ValueError, IndexError), v:
+ raise ConversionError(_("Invalid datetime data"), v)
+
+class DateWidget(DatetimeWidget):
"""Date entry widget.
+ """
+ def _toFieldValue(self, input):
+ v = super(DateWidget, self)._toFieldValue(input)
+ if v != self.context.missing_value:
+ v = v.date()
+ return v
+
+class DateI18nWidget(TextWidget):
+ """I18n date entry widget.
+
The `displayStyle` attribute may be set to control the formatting of the
value.
@@ -513,15 +543,15 @@
"%s (%r)" % (v, input))
def _toFormValue(self, value):
- value = super(DateWidget, self)._toFormValue(value)
+ value = super(DateI18nWidget, self)._toFormValue(value)
if value:
formatter = self.request.locale.dates.getFormatter(
self._category, (self.displayStyle or None))
value = formatter.format(value)
return value
-class DatetimeWidget(DateWidget):
- """Datetime entry widget.
+class DatetimeI18nWidget(DateI18nWidget):
+ """I18n datetime entry widget.
The `displayStyle` attribute may be set to control the formatting of the
value.
Modified: Zope3/trunk/src/zope/formlib/form.txt
===================================================================
--- Zope3/trunk/src/zope/formlib/form.txt 2006-07-01 17:18:56 UTC (rev 68937)
+++ Zope3/trunk/src/zope/formlib/form.txt 2006-07-01 17:37:13 UTC (rev 68938)
@@ -1554,7 +1554,7 @@
<input class="textType" id="form.max_size" name="form.max_size"
size="10" type="text" value="" />
<input class="textType" id="form.now" name="form.now" size="20"
- type="text" value="2002 12 2 12:30:00 " />
+ type="text" value="2002-12-02 12:30:00" />
Note that a EditForm can't make use of a get_rendered method. The get_rendered
method does only set initial values.
More information about the Zope3-Checkins
mailing list