Bläddra i källkod

datetimeex.Duration: added 'days' attr

Fabian Peter Hammerle 8 år sedan
förälder
incheckning
a4794761cb
3 ändrade filer med 83 tillägg och 32 borttagningar
  1. 14 9
      ioex/datetimeex.py
  2. 65 23
      tests/datetimeex/test_duration.py
  3. 4 0
      tests/datetimeex/test_duration_yaml.py

+ 14 - 9
ioex/datetimeex.py

@@ -18,9 +18,10 @@ def construct_yaml_timestamp(loader, node):
             timezone_attr = timezone_match.groupdict()
             if timezone_attr['h']:
                 timezone = dateutil.tz.tz.tzoffset(
-                    name = timezone_match.group(0),
-                    offset = (int(timezone_attr['h']) * 60 + int(timezone_attr['m'])) * 60
-                        * (-1 if timezone_attr['sign'] == '-' else 1),
+                    name=timezone_match.group(0),
+                    offset=(
+                        int(timezone_attr['h']) * 60 + int(timezone_attr['m'])) * 60
+                         * (-1 if timezone_attr['sign'] == '-' else 1),
                 )
                 loaded_dt = loaded_dt.astimezone(timezone)
     return loaded_dt
@@ -35,22 +36,25 @@ class Duration(object):
     yaml_tag = u'!duration'
 
     years = ioex.classex.AttributeDescriptor('_years', types=(int,), min=0)
+    days = ioex.classex.AttributeDescriptor('_days', types=(int,), min=0)
 
-    def __init__(self, years=0):
+    def __init__(self, years=0, days=0):
         self.years = years
+        self.days = days
 
     @property
     def isoformat(self):
         iso_str = re.sub(
             r'(?<!\d)0.',
             '',
-            'P{}Y'.format(self.years),
+            'P{}Y{}D'.format(self.years, self.days),
         )
         return 'P0Y' if iso_str == 'P' else iso_str
 
     def __eq__(self, other):
         return (type(self) == type(other)
-                and self.years == other.years)
+                and self.years == other.years
+                and self.days == other.days)
 
     @classmethod
     def from_yaml(cls, loader, node):
@@ -66,7 +70,8 @@ class Duration(object):
             tag=tag,
             mapping={k: v for k, v in {
                 'years': duration.years,
-                }.items() if v != 0},
+                'days': duration.days,
+            }.items() if v != 0},
         )
 
     @classmethod
@@ -131,9 +136,9 @@ class Period(object):
         match = re.search('^%s$' % self.__class__._timeperiod_iso_format, text)
         if not match:
             raise ValueError(
-                    "given string '%s' does not match the supported pattern '%s'"
+                "given string '%s' does not match the supported pattern '%s'"
                      % (text, self.__class__._timeperiod_iso_format)
-                     )
+            )
         attr = match.groupdict()
         self.start = dateutil.parser.parse(attr['start'])
         self.end = dateutil.parser.parse(attr['end'])

+ 65 - 23
tests/datetimeex/test_duration.py

@@ -3,59 +3,101 @@ import pytest
 
 from ioex.datetimeex import Duration
 
-@pytest.mark.parametrize(('years'), [
-    0,
-    13,
-    ])
-def test_init(years):
-    d = Duration(years = years)
-    assert d.years == years
+
+@pytest.mark.parametrize(('init_kwargs'), [
+    {'years': 0},
+    {'years': 13},
+    {'days': 0},
+    {'days': 13},
+    {'years': 1, 'days': 3},
+])
+def test_init(init_kwargs):
+    d = Duration(**init_kwargs)
+    for attr in ['years', 'days']:
+        if attr in init_kwargs:
+            assert init_kwargs[attr] == getattr(d, attr)
+        else:
+            assert 0 == getattr(d, attr)
+
 
 def test_init_default():
     d = Duration()
-    assert d.years == 0
-    None,
+    assert 0 == d.years
+    assert 0 == d.days
 
-@pytest.mark.parametrize(('years', 'exception_type'), [
-    [-2, ValueError],
-    ['1', TypeError],
-    ])
-def test_init_fail(years, exception_type):
+
+@pytest.mark.parametrize(('init_kwargs', 'exception_type'), [
+    [{'years': -2}, ValueError],
+    [{'years': '1'}, TypeError],
+    [{'days': -2}, ValueError],
+    [{'days': '1'}, TypeError],
+])
+def test_init_fail(init_kwargs, exception_type):
     with pytest.raises(exception_type):
-        Duration(years = years)
+        Duration(**init_kwargs)
+
 
 @pytest.mark.parametrize(('years'), [
     0,
     13,
-    ])
+])
 def test_set_years(years):
     d = Duration()
     d.years = years
     assert d.years == years
 
+
 @pytest.mark.parametrize(('years', 'exception_type'), [
     [-2, ValueError],
     ['1', TypeError],
-    ])
+])
 def test_set_years_fail(years, exception_type):
     d = Duration()
     with pytest.raises(exception_type):
         d.years = years
 
+
+@pytest.mark.parametrize(('days'), [
+    0,
+    13,
+])
+def test_set_days(days):
+    d = Duration()
+    d.days = days
+    assert d.days == days
+
+
+@pytest.mark.parametrize(('days', 'exception_type'), [
+    [-2, ValueError],
+    ['1', TypeError],
+])
+def test_set_days_fail(days, exception_type):
+    d = Duration()
+    with pytest.raises(exception_type):
+        d.days = days
+
+
 @pytest.mark.parametrize(('init_params', 'iso'), [
     [{'years': 0}, 'P0Y'],
-    [{'years': 3}, 'P3Y'],
     [{'years': 30}, 'P30Y'],
-    ])
+    [{'years': 3}, 'P3Y'],
+    [{'days': 30}, 'P30D'],
+    [{'days': 3}, 'P3D'],
+    [{'years': 10, 'days': 30}, 'P10Y30D'],
+])
 def test_get_isoformat(init_params, iso):
     d = Duration(**init_params)
     assert d.isoformat == iso
 
+
 @pytest.mark.parametrize(('a', 'b'), [
-    [Duration(), Duration(years = 0)],
-    [Duration(years = 0), Duration(years = 0)],
-    [Duration(years = 3), Duration(years = 3)],
-    ])
+    [Duration(), Duration(years=0, days=0)],
+    [Duration(years=0), Duration(years=0)],
+    [Duration(years=3), Duration(years=3)],
+    [Duration(days=0), Duration(days=0)],
+    [Duration(days=3), Duration(days=3)],
+    [Duration(years=1, days=3), Duration(years=1, days=3)],
+])
 def test_eq(a, b):
     assert a == b
     assert b == a

+ 4 - 0
tests/datetimeex/test_duration_yaml.py

@@ -11,6 +11,8 @@ yaml = pytest.importorskip('yaml')
     [Duration(years=32), '!duration\nyears: 32'],
     [Duration(years=0),  '!duration\n{}'],
     [Duration(years=0),  '!duration {}'],
+    [Duration(days=32), '!duration\ndays: 32'],
+    [Duration(years=1, days=3), '!duration\nyears: 1\ndays: 3'],
 ])
 def test_from_yaml(expected_duration, yaml_string, loader):
     class TestLoader(loader):
@@ -37,6 +39,8 @@ def test_from_yaml_tag(expected_duration, yaml_string, tag, loader):
 @pytest.mark.parametrize(('duration', 'yaml_string'), [
     [Duration(years=0),  '!duration {}\n'],
     [Duration(years=32), '!duration\nyears: 32\n'],
+    [Duration(days=32), '!duration\ndays: 32\n'],
+    [Duration(years=1, days=2), '!duration\ndays: 2\nyears: 1\n'],
 ])
 def test_to_yaml(duration, yaml_string, dumper):
     class TestDumper(dumper):