Browse Source

yaml support for Order

Fabian Peter Hammerle 8 years ago
parent
commit
4f2f5e5f66
3 changed files with 131 additions and 22 deletions
  1. 29 14
      dingguo/__init__.py
  2. 14 5
      tests/test_comparison.py
  3. 88 3
      tests/test_yaml.py

+ 29 - 14
dingguo/__init__.py

@@ -6,7 +6,16 @@ import datetime
 
 yaml.Dumper.add_representer(unicode, yaml.representer.SafeRepresenter.represent_unicode)
 
-class Figure(yaml.YAMLObject):
+class _YamlUnicodeConstruct(yaml.YAMLObject):
+
+    @classmethod
+    def from_yaml(cls, loader, node):
+        return cls(**{
+            k: unicode(v) if isinstance(v, str) else v
+                for (k, v) in loader.construct_mapping(node, deep = True).items()
+            })
+
+class Figure(_YamlUnicodeConstruct):
 
     yaml_tag = u"!figure"
 
@@ -39,14 +48,6 @@ class Figure(yaml.YAMLObject):
     def __ne__(self, other):
         return not (self == other)
 
-    @classmethod
-    def from_yaml(cls, loader, node):
-        attr = loader.construct_mapping(node)
-        return cls(
-                value = attr['value'],
-                unit = unicode(attr['unit']),
-                )
-
     @classmethod
     def to_yaml(cls, dumper, figure):
         return dumper.represent_mapping(
@@ -151,9 +152,15 @@ class Discount(yaml.YAMLObject):
 
 yaml.SafeDumper.add_representer(Discount, lambda dumper, discount: dumper.represent_dict(discount.dict_repr()))
 
-class Order(object):
+class Order(_YamlUnicodeConstruct):
 
-    def __init__(self, platform, order_id, order_date, customer_id = None):
+    yaml_tag = u'!order'
+
+    def __init__(self, platform, order_id, order_date,
+            customer_id = None,
+            items = None,
+            discounts = None,
+            ):
         assert type(platform) is unicode
         self.platform = platform
         assert type(order_id) is unicode
@@ -164,8 +171,14 @@ class Order(object):
         self.order_date = order_date
         assert customer_id is None or type(customer_id) is unicode
         self.customer_id = customer_id
-        self.items = []
-        self.discounts = []
+        if items is None:
+            items = []
+        assert type(items) is list
+        self.items = items
+        if discounts is None:
+            discounts = []
+        assert type(discounts) is list
+        self.discounts = discounts
 
     def dict_repr(self):
         return {k: v for (k, v) in {
@@ -211,7 +224,9 @@ class Order(object):
 
 yaml.SafeDumper.add_representer(Order, lambda dumper, order: dumper.represent_dict(order.dict_repr()))
 
-class Item(object):
+class Item(_YamlUnicodeConstruct):
+
+    yaml_tag = u'!item'
 
     def __init__(
             self,

+ 14 - 5
tests/test_comparison.py

@@ -30,15 +30,16 @@ def get_discount_b():
             amount = dingguo.Sum(2.0, u'EUR'),
             )
 
-def get_order_a():
+def get_order_a(items = True):
     order = dingguo.Order(
             platform = u'platform',
             order_id = u'id',
             order_date = datetime.datetime(2016, 5, 8, 0, 18, 17),
             customer_id = u'customer',
             )
-    order.items.append(get_item_a())
-    order.items.append(get_item_b())
+    if items:
+        order.items.append(get_item_a())
+        order.items.append(get_item_b())
     order.discounts.append(get_discount_a())
     order.discounts.append(get_discount_b())
     return order
@@ -118,12 +119,20 @@ def test_order_eq_inverted():
     assert not get_order_b() == get_order_a()
     assert not get_order_c() == get_order_b()
 
-def test_order_neq():
+def test_order_ne():
     assert get_order_a() != get_order_c()
     assert get_order_b() != get_order_a()
     assert get_order_c() != get_order_b()
 
-def test_order_neq_inverted():
+def test_order_ne_inverted():
     assert not get_order_a() != get_order_a()
     assert not get_order_b() != get_order_b()
     assert not get_order_c() != get_order_c()
+
+def test_order_ne_items():
+    assert get_order_a() != get_order_a(items = False)
+
+def test_order_ne_items_reversed():
+    order = get_order_a()
+    order.items = order.items[::-1]
+    assert get_order_a() != order

+ 88 - 3
tests/test_yaml.py

@@ -5,11 +5,9 @@ import pytest
 import os
 import yaml
 import dingguo
+import difflib
 import datetime
 
-project_root_path = os.path.realpath(os.path.join(__file__, '..', '..'))
-test_data_path = os.path.join(project_root_path, 'tests', 'data')
-
 def get_figure_a():
     return dingguo.Figure(12.3, u'km')
 
@@ -22,9 +20,38 @@ def get_sum_a():
 def get_sum_b():
     return dingguo.Sum(20.45, u'€')
 
+def get_item_a():
+    return dingguo.Item(
+            name = u'item a',
+            price_brutto = get_sum_a(),
+            )
+
+def get_item_b():
+    return dingguo.Item(
+            name = u'item β',
+            price_brutto = get_sum_b(),
+            )
+
+def get_order_a():
+    order = dingguo.Order(
+            platform = u'platformπ',
+            order_id = u'id',
+            order_date = datetime.datetime(2016, 5, 8, 0, 18, 17),
+            customer_id = u'customer',
+            )
+    order.items.append(get_item_a())
+    order.items.append(get_item_b())
+    return order
+
 def to_yaml(data):
     return yaml.dump(data, default_flow_style = False, allow_unicode = True).decode('utf-8')
 
+def yaml_diff(a, b):
+    return '\n'.join(difflib.ndiff(
+        to_yaml(a).split('\n'),
+        to_yaml(b).split('\n'),
+        ))
+
 def test_figure_to_yaml():
     assert to_yaml(get_figure_a()) == u"""!figure
 unit: km
@@ -63,3 +90,61 @@ def test_sum_from_yaml_a_sign():
 
 def test_sum_from_yaml_a_quotes():
     assert get_sum_a() == yaml.load(u"!sum 'EUR 1.23'")
+
+def test_item_to_yaml_a():
+    assert to_yaml(get_item_a()) == u"""!item
+name: item a
+price_brutto: !sum 'EUR 1.23'
+"""
+
+def test_item_to_yaml_b():
+    assert to_yaml(get_item_b()) == u"""!item
+name: item β
+price_brutto: !sum 'EUR 20.45'
+"""
+
+def test_item_from_yaml_a():
+    assert get_item_a() == yaml.load(u"""!item
+name: item a
+price_brutto: !sum 'EUR 1.23'
+""")
+
+def test_item_from_yaml_b():
+    assert get_item_b() == yaml.load(u"""!item
+name: item β
+price_brutto: !sum 'EUR 20.45'
+""")
+
+def test_order_to_yaml():
+    assert to_yaml(get_order_a()) == u"""!order
+customer_id: customer
+discounts: []
+items:
+- !item
+  name: item a
+  price_brutto: !sum 'EUR 1.23'
+- !item
+  name: item β
+  price_brutto: !sum 'EUR 20.45'
+order_date: 2016-05-08
+order_id: id
+platform: platformπ
+"""
+
+def test_order_from_yaml():
+    order_loaded = yaml.load(u"""!order
+customer_id: customer
+discounts: []
+items:
+- !item
+  name: item a
+  price_brutto: !sum 'EUR 1.23'
+- !item
+  name: item β
+  price_brutto: !sum 'EUR 20.45'
+order_date: 2016-05-08
+order_id: id
+platform: platformπ
+""")
+    order_expected = get_order_a()
+    assert order_expected == order_loaded, yaml_diff(order_expected, order_loaded)