test the iso8601 package and add a licensing exception

This commit is contained in:
Chris McDonough
2012-02-04 10:18:44 -05:00
parent 8f06c0a7ed
commit ef7b467900
5 changed files with 170 additions and 25 deletions

View File

@@ -39,3 +39,6 @@ License
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
This package uses code from the "pyiso8601" package by Michael Twomey,
licensed under the MIT license. See the source file named "iso8601.py" for
copyright information and license text.

View File

@@ -1,13 +1,35 @@
"""ISO 8601 date time string parsing
"""
Copyright (c) 2007 Michael Twomey
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
ISO 8601 date time string parsing
Basic usage:
>>> import iso8601
>>> iso8601.parse_date("2007-01-25T12:00:00Z")
datetime.datetime(2007, 1, 25, 12, 0, tzinfo=<iso8601.iso8601.Utc ...>)
>>>
"""
from datetime import datetime, timedelta, tzinfo
import re
@@ -16,11 +38,13 @@ from .compat import string_types
__all__ = ["parse_date", "ParseError", "Utc", "FixedOffset"]
# Adapted from http://delete.me.uk/2005/03/iso8601.html
ISO8601_REGEX = re.compile(r"(?P<year>[0-9]{4})(-(?P<month>[0-9]{1,2})(-(?P<day>[0-9]{1,2})"
ISO8601_REGEX = re.compile(
r"(?P<year>[0-9]{4})(-(?P<month>[0-9]{1,2})(-(?P<day>[0-9]{1,2})"
r"((?P<separator>.)(?P<hour>[0-9]{2}):(?P<minute>[0-9]{2})(:(?P<second>[0-9]{2})(\.(?P<fraction>[0-9]+))?)?"
r"(?P<timezone>Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?"
)
TIMEZONE_REGEX = re.compile("(?P<prefix>[+-])(?P<hours>[0-9]{2}).(?P<minutes>[0-9]{2})")
TIMEZONE_REGEX = re.compile(
"(?P<prefix>[+-])(?P<hours>[0-9]{2}).(?P<minutes>[0-9]{2})")
class ParseError(Exception):
"""Raised when there is a problem parsing a date string"""

View File

@@ -0,0 +1,2 @@
# package
fixture = 1

View File

@@ -1,6 +1,6 @@
# -*- coding:utf-8 -*-
import unittest
from .compat import text_, text_type
from colander.compat import text_, text_type
def invalid_exc(func, *arg, **kw):
from colander import Invalid
@@ -1244,7 +1244,7 @@ class TestGlobalObject(unittest.TestCase):
def test_zope_dottedname_style_resolve_absolute(self):
typ = self._makeOne()
result = typ._zope_dottedname_style(None,
'colander.tests.TestGlobalObject')
'colander.tests.test_colander.TestGlobalObject')
self.assertEqual(result, self.__class__)
def test_zope_dottedname_style_irrresolveable_absolute(self):
@@ -1256,14 +1256,18 @@ class TestGlobalObject(unittest.TestCase):
import colander
typ = self._makeOne(package=colander)
node = DummySchemaNode(None)
result = typ._zope_dottedname_style(node, '.tests.TestGlobalObject')
result = typ._zope_dottedname_style(
node,
'.tests.test_colander.TestGlobalObject')
self.assertEqual(result, self.__class__)
def test__zope_dottedname_style_resolve_relative_leading_dots(self):
import colander
typ = self._makeOne(package=colander.tests)
node = DummySchemaNode(None)
result = typ._zope_dottedname_style(node, '..tests.TestGlobalObject')
result = typ._zope_dottedname_style(
node,
'..tests.test_colander.TestGlobalObject')
self.assertEqual(result, self.__class__)
def test__zope_dottedname_style_resolve_relative_is_dot(self):
@@ -1301,36 +1305,40 @@ class TestGlobalObject(unittest.TestCase):
def test__zope_dottedname_style_irresolveable_absolute(self):
typ = self._makeOne()
self.assertRaises(ImportError,
typ._zope_dottedname_style, None, 'colander.fudge.bar')
self.assertRaises(
ImportError,
typ._zope_dottedname_style, None, 'colander.fudge.bar')
def test__zope_dottedname_style_resolveable_absolute(self):
typ = self._makeOne()
result = typ._zope_dottedname_style(None,
'colander.tests.TestGlobalObject')
result = typ._zope_dottedname_style(
None,
'colander.tests.test_colander.TestGlobalObject')
self.assertEqual(result, self.__class__)
def test__pkg_resources_style_resolve_absolute(self):
typ = self._makeOne()
result = typ._pkg_resources_style(None,
'colander.tests:TestGlobalObject')
'colander.tests.test_colander:TestGlobalObject')
self.assertEqual(result, self.__class__)
def test__pkg_resources_style_irrresolveable_absolute(self):
typ = self._makeOne()
self.assertRaises(ImportError, typ._pkg_resources_style, None,
'colander.tests:nonexisting')
'colander.tests.test_colander:nonexisting')
def test__pkg_resources_style_resolve_relative_startswith_colon(self):
import colander.tests
typ = self._makeOne(package=colander.tests)
result = typ._pkg_resources_style(None, ':TestGlobalObject')
self.assertEqual(result, self.__class__)
result = typ._pkg_resources_style(None, ':fixture')
self.assertEqual(result, 1)
def test__pkg_resources_style_resolve_relative_startswith_dot(self):
import colander
typ = self._makeOne(package=colander)
result = typ._pkg_resources_style(None, '.tests:TestGlobalObject')
result = typ._pkg_resources_style(
None,
'.tests.test_colander:TestGlobalObject')
self.assertEqual(result, self.__class__)
def test__pkg_resources_style_resolve_relative_is_dot(self):
@@ -1374,13 +1382,17 @@ class TestGlobalObject(unittest.TestCase):
def test_deserialize_using_pkgresources_style(self):
typ = self._makeOne()
node = DummySchemaNode(None)
result = typ.deserialize(node, 'colander.tests:TestGlobalObject')
result = typ.deserialize(
node,
'colander.tests.test_colander:TestGlobalObject')
self.assertEqual(result, self.__class__)
def test_deserialize_using_zope_dottedname_style(self):
typ = self._makeOne()
node = DummySchemaNode(None)
result = typ.deserialize(node, 'colander.tests.TestGlobalObject')
result = typ.deserialize(
node,
'colander.tests.test_colander.TestGlobalObject')
self.assertEqual(result, self.__class__)
def test_deserialize_style_raises(self):
@@ -1425,12 +1437,12 @@ class TestDateTime(unittest.TestCase):
return datetime.date.today()
def test_ctor_default_tzinfo_None(self):
from . import iso8601
from .. import iso8601
typ = self._makeOne()
self.assertEqual(typ.default_tzinfo.__class__, iso8601.Utc)
def test_ctor_default_tzinfo_non_None(self):
from . import iso8601
from .. import iso8601
tzinfo = iso8601.FixedOffset(1, 0, 'myname')
typ = self._makeOne(default_tzinfo=tzinfo)
self.assertEqual(typ.default_tzinfo, tzinfo)
@@ -1476,7 +1488,7 @@ class TestDateTime(unittest.TestCase):
self.assertEqual(result, dt.isoformat())
def test_serialize_with_tzware_datetime(self):
from . import iso8601
from .. import iso8601
typ = self._makeOne()
dt = self._dt()
tzinfo = iso8601.FixedOffset(1, 0, 'myname')
@@ -1488,7 +1500,7 @@ class TestDateTime(unittest.TestCase):
def test_deserialize_date(self):
import datetime
from . import iso8601
from .. import iso8601
date = self._today()
typ = self._makeOne()
formatted = date.isoformat()
@@ -1520,7 +1532,7 @@ class TestDateTime(unittest.TestCase):
self.assertEqual(result, colander.null)
def test_deserialize_success(self):
from . import iso8601
from .. import iso8601
typ = self._makeOne()
dt = self._dt()
tzinfo = iso8601.FixedOffset(1, 0, 'myname')
@@ -1531,7 +1543,7 @@ class TestDateTime(unittest.TestCase):
self.assertEqual(result.isoformat(), iso)
def test_deserialize_naive_with_default_tzinfo(self):
from . import iso8601
from .. import iso8601
tzinfo = iso8601.FixedOffset(1, 0, 'myname')
typ = self._makeOne(default_tzinfo=tzinfo)
dt = self._dt()

View File

@@ -0,0 +1,104 @@
import unittest
import datetime
class Test_Utc(unittest.TestCase):
def _makeOne(self):
from ..iso8601 import Utc
return Utc()
def test_utcoffset(self):
from ..iso8601 import ZERO
inst = self._makeOne()
result = inst.utcoffset(None)
self.assertEqual(result, ZERO)
def test_tzname(self):
inst = self._makeOne()
result = inst.tzname(None)
self.assertEqual(result, "UTC")
def test_dst(self):
from ..iso8601 import ZERO
inst = self._makeOne()
result = inst.dst(None)
self.assertEqual(result, ZERO)
class Test_FixedOffset(unittest.TestCase):
def _makeOne(self):
from ..iso8601 import FixedOffset
return FixedOffset(1, 30, 'oneandahalf')
def test_utcoffset(self):
inst = self._makeOne()
result = inst.utcoffset(None)
self.assertEqual(result, datetime.timedelta(hours=1, minutes=30))
def test_tzname(self):
inst = self._makeOne()
result = inst.tzname(None)
self.assertEqual(result, 'oneandahalf')
def test_dst(self):
from ..iso8601 import ZERO
inst = self._makeOne()
result = inst.dst(None)
self.assertEqual(result, ZERO)
def test___repr__(self):
inst = self._makeOne()
result = inst.__repr__()
self.assertEqual(result, "<FixedOffset 'oneandahalf'>")
class Test_parse_timezone(unittest.TestCase):
def _callFUT(self, tzstring):
from ..iso8601 import parse_timezone
return parse_timezone(tzstring)
def test_default_Z(self):
from ..iso8601 import UTC
result = self._callFUT('Z')
self.assertEqual(result, UTC)
def test_default_None(self):
from ..iso8601 import UTC
result = self._callFUT(None)
self.assertEqual(result, UTC)
def test_positive(self):
tzstring = "+01:00"
result = self._callFUT(tzstring)
self.assertEqual(result.utcoffset(None),
datetime.timedelta(hours=1, minutes=0))
def test_negative(self):
tzstring = "-01:00"
result = self._callFUT(tzstring)
self.assertEqual(result.utcoffset(None),
datetime.timedelta(hours=-1, minutes=0))
class Test_parse_date(unittest.TestCase):
def _callFUT(self, datestring):
from ..iso8601 import parse_date
return parse_date(datestring)
def test_notastring(self):
from ..iso8601 import ParseError
self.assertRaises(ParseError, self._callFUT, None)
def test_cantparse(self):
from ..iso8601 import ParseError
self.assertRaises(ParseError, self._callFUT, 'garbage')
def test_normal(self):
from ..iso8601 import UTC
result = self._callFUT("2007-01-25T12:00:00Z")
self.assertEqual(result,
datetime.datetime(2007, 1, 25, 12, 0, tzinfo=UTC))
def test_fraction(self):
from ..iso8601 import UTC
result = self._callFUT("2007-01-25T12:00:00.123Z")
self.assertEqual(result,
datetime.datetime(2007, 1, 25, 12, 0, 0, 123000,
tzinfo=UTC))