test_yaml.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. # -*- coding: utf-8 -*-
  2. import pytest
  3. import datetime
  4. import difflib
  5. import finoex
  6. import ioex.calcex
  7. import ioex.datetimeex
  8. import os
  9. import pytz
  10. yaml = pytest.importorskip('yaml')
  11. def get_figure_a():
  12. return ioex.calcex.Figure(12.3, u'km')
  13. def get_figure_b():
  14. return ioex.calcex.Figure(12300, u'米')
  15. def get_sum_a():
  16. return finoex.Sum(1.23, u'EUR')
  17. def get_sum_b():
  18. return finoex.Sum(20.45, u'€')
  19. def get_item_a():
  20. return finoex.Item(
  21. name = u'item a',
  22. price_brutto = get_sum_a(),
  23. )
  24. def get_item_b():
  25. return finoex.Item(
  26. name = u'item β',
  27. price_brutto = get_sum_b(),
  28. )
  29. def get_service():
  30. return finoex.Service(
  31. name = u'service',
  32. price_brutto = finoex.Sum(1.0, u'EUR'),
  33. duration = ioex.datetimeex.Duration(years = 2),
  34. state = 'success',
  35. )
  36. def get_person_a():
  37. return finoex.Person(
  38. first_name = u'Fabian Peter',
  39. last_name = u'Hammerle',
  40. )
  41. def get_person_b():
  42. return finoex.Person(
  43. first_name = u'名字',
  44. last_name = u'贵姓',
  45. )
  46. def get_campaign_a():
  47. return finoex.Campaign(
  48. name = u'campaign a',
  49. founder = u'company',
  50. end = datetime.datetime(2016, 7, 23, 9, 23, 17, tzinfo = pytz.timezone('Europe/Vienna')),
  51. )
  52. def get_campaign_b():
  53. return finoex.Campaign(
  54. founder = u'company',
  55. name = u'campaign without end',
  56. website_url = u'http://campaign.com',
  57. )
  58. def get_pledge():
  59. return finoex.Pledge(
  60. campaign = get_campaign_a(),
  61. price_brutto = finoex.Sum(10.0, u'EUR'),
  62. reward = u'great',
  63. )
  64. def get_contribution():
  65. return finoex.Contribution(
  66. campaign = get_campaign_a(),
  67. price_brutto = finoex.Sum(10.0, u'EUR'),
  68. reward = u'product',
  69. )
  70. def get_article():
  71. return finoex.Article(
  72. authors = ['a', 'b'],
  73. depth = finoex.Distance(12.3, u'dm'),
  74. features = u'supergeil',
  75. height = finoex.Distance(123., u'cm'),
  76. maximum_load = ioex.calcex.Figure(40., u'kg'),
  77. name = u'article name',
  78. price_brutto = get_sum_a(),
  79. product_id = u'0815',
  80. quantity = 1,
  81. reseller = u'seller',
  82. shipper = u'shipper',
  83. state = u'goood',
  84. width = finoex.Distance(1.23, u'm'),
  85. )
  86. def get_transportation():
  87. return finoex.Transportation(
  88. name = u'ticket',
  89. price_brutto = get_sum_a(),
  90. departure_point = u'home',
  91. destination_point = u'city',
  92. distance = finoex.Distance(3.21, u'km'),
  93. passenger = get_person_a(),
  94. valid_from = datetime.datetime(2016, 7, 14, 13, 50, 4, 0, tzinfo = pytz.timezone('Europe/Vienna')),
  95. valid_until = datetime.datetime(2016, 7, 14, 18, 50, 4, 0, tzinfo = pytz.utc),
  96. ticket_url = u'https://www.example.com',
  97. estimated_arrival_time = ioex.datetimeex.Period(
  98. start = pytz.timezone('Europe/Vienna').localize(datetime.datetime(2016, 7, 24, 23, 47, 2)),
  99. end = pytz.utc.localize(datetime.datetime(2016, 7, 24, 23, 48, 5)),
  100. ),
  101. )
  102. def get_shipping():
  103. return finoex.Shipping(
  104. price_brutto = get_sum_a(),
  105. destination_point = u'home',
  106. )
  107. def get_taxi_ride():
  108. return finoex.TaxiRide(
  109. name = u'taxi ride',
  110. price_brutto = get_sum_a(),
  111. departure_point = u'home',
  112. destination_point = u'city',
  113. distance = finoex.Distance(3.21, u'km'),
  114. driver = u'driver',
  115. arrival_time = datetime.datetime(2016, 5, 2, 18, 10, tzinfo = pytz.timezone('Europe/Vienna')),
  116. departure_time = datetime.datetime(2016, 5, 2, 18, 25, tzinfo = pytz.timezone('Europe/Vienna')),
  117. )
  118. def get_discount_a():
  119. return finoex.Discount(
  120. name = u'discount a',
  121. amount = get_sum_a(),
  122. )
  123. def get_discount_b():
  124. return finoex.Discount(
  125. name = u'discount β',
  126. amount = get_sum_b(),
  127. )
  128. def get_order_a(items = True, discounts = True):
  129. order = finoex.Order(
  130. platform = u'platformπ',
  131. order_id = u'id',
  132. order_date = datetime.datetime(2016, 5, 8, 0, 18, 17),
  133. customer_id = u'customer',
  134. )
  135. if items:
  136. order.items.append(get_item_a())
  137. order.items.append(get_item_b())
  138. if discounts:
  139. order.discounts.append(get_discount_a())
  140. order.discounts.append(get_discount_b())
  141. return order
  142. def get_order_b():
  143. order = finoex.Order(
  144. platform = u'platformπ',
  145. order_id = u'order_b',
  146. order_date = datetime.datetime(2015, 5, 8, 0, 18, 17),
  147. )
  148. return order
  149. def get_order_c():
  150. order = finoex.Order(
  151. platform = u'γάμμα',
  152. order_id = u'order_βήτα',
  153. order_date = datetime.datetime(2014, 5, 8, 0, 18, 17),
  154. customer_id = u'ρώ',
  155. )
  156. return order
  157. def get_invoice(items = True):
  158. inv = finoex.Invoice(
  159. creditor = u'platformπ',
  160. invoice_id = u'id',
  161. invoice_date = datetime.datetime(2016, 5, 8, 0, 18, 17),
  162. debitor_id = u'customer',
  163. )
  164. if items:
  165. inv.items.append(get_item_a())
  166. inv.items.append(get_item_b())
  167. return inv
  168. def get_distance():
  169. return finoex.Distance(2.4142, u'km')
  170. def to_yaml(data):
  171. class Dumper(yaml.Dumper):
  172. pass
  173. ioex.datetimeex.Duration.register_yaml_representer(yaml.Dumper)
  174. ioex.datetimeex.Period.register_yaml_representer(yaml.Dumper)
  175. ioex.calcex.Figure.register_yaml_representer(yaml.Dumper)
  176. finoex.Sum.register_yaml_representer(yaml.Dumper)
  177. finoex.Distance.register_yaml_representer(yaml.Dumper)
  178. return yaml.dump(
  179. data,
  180. default_flow_style = False,
  181. allow_unicode = True,
  182. Dumper = Dumper,
  183. ) #.decode('utf-8')
  184. def yaml_diff(a, b):
  185. return '\n'.join(difflib.ndiff(
  186. to_yaml(a).split('\n'),
  187. to_yaml(b).split('\n'),
  188. ))
  189. @pytest.mark.parametrize('source_object,expected_yaml', [
  190. [datetime.datetime(2016, 7, 14, 13, 50, 4, 0), '2016-07-14 13:50:04\n...\n'],
  191. [datetime.datetime(2016, 7, 14, 13, 50, 4, 0, tzinfo = pytz.timezone('Europe/Vienna')), '2016-07-14 13:50:04+01:05\n...\n'],
  192. [datetime.datetime(2016, 7, 14, 13, 50, 4, 0, tzinfo = pytz.utc), '2016-07-14 13:50:04+00:00\n...\n'],
  193. [finoex.Distance(1.34, u'km'), u"!distance '1.34 km'\n"],
  194. [finoex.Distance(1.34, u'μm'), u"!distance '1.34 μm'\n"],
  195. [get_discount_a(), u"!discount\namount: !sum '1.23 EUR'\nname: discount a\n"],
  196. [get_discount_b(), u"!discount\namount: !sum '20.45 EUR'\nname: discount β\n"],
  197. [get_figure_a(), u"!figure '12.3 km'\n"],
  198. [get_figure_b(), u"!figure '12300 米'\n"],
  199. [get_item_a(), u"!item\nname: item a\nprice_brutto: !sum '1.23 EUR'\n"],
  200. [get_item_b(), u"!item\nname: item β\nprice_brutto: !sum '20.45 EUR'\n"],
  201. [get_person_a(), u'!person\nfirst_name: Fabian Peter\nlast_name: Hammerle\n'],
  202. [get_person_b(), u'!person\nfirst_name: 名字\nlast_name: 贵姓\n'],
  203. [get_campaign_a(), u"""!campaign
  204. end: 2016-07-23 09:23:17+01:05
  205. founder: company
  206. name: campaign a
  207. """],
  208. [get_campaign_b(), u"""!campaign
  209. founder: company
  210. name: campaign without end
  211. website_url: http://campaign.com
  212. """],
  213. [get_service(), u"""!service
  214. duration: !duration
  215. years: 2
  216. name: service
  217. price_brutto: !sum '1.0 EUR'
  218. state: success
  219. """],
  220. [get_pledge(), u"""!pledge
  221. campaign: !campaign
  222. end: 2016-07-23 09:23:17+01:05
  223. founder: company
  224. name: campaign a
  225. price_brutto: !sum '10.0 EUR'
  226. reward: great
  227. """],
  228. [get_contribution(), u"""!contribution
  229. campaign: !campaign
  230. end: 2016-07-23 09:23:17+01:05
  231. founder: company
  232. name: campaign a
  233. price_brutto: !sum '10.0 EUR'
  234. reward: product
  235. """],
  236. [get_order_a(), u"""!order
  237. customer_id: customer
  238. discounts:
  239. - !discount
  240. amount: !sum '1.23 EUR'
  241. name: discount a
  242. - !discount
  243. amount: !sum '20.45 EUR'
  244. name: discount β
  245. items:
  246. - !item
  247. name: item a
  248. price_brutto: !sum '1.23 EUR'
  249. - !item
  250. name: item β
  251. price_brutto: !sum '20.45 EUR'
  252. order_date: 2016-05-08 00:18:17
  253. order_id: id
  254. platform: platformπ
  255. """],
  256. [get_order_a(discounts = False), u"""!order
  257. customer_id: customer
  258. items:
  259. - !item
  260. name: item a
  261. price_brutto: !sum '1.23 EUR'
  262. - !item
  263. name: item β
  264. price_brutto: !sum '20.45 EUR'
  265. order_date: 2016-05-08 00:18:17
  266. order_id: id
  267. platform: platformπ
  268. """],
  269. [get_article(), u"""!article
  270. authors:
  271. - a
  272. - b
  273. depth: !distance '12.3 dm'
  274. features: supergeil
  275. height: !distance '123.0 cm'
  276. maximum_load: !figure '40.0 kg'
  277. name: article name
  278. price_brutto: !sum '1.23 EUR'
  279. product_id: 0815
  280. quantity: 1
  281. reseller: seller
  282. shipper: shipper
  283. state: goood
  284. width: !distance '1.23 m'
  285. """],
  286. [get_transportation(), u"""!transportation
  287. departure_point: home
  288. destination_point: city
  289. distance: !distance '3.21 km'
  290. estimated_arrival_time: !period
  291. end: 2016-07-24 23:48:05+00:00
  292. start: 2016-07-24 23:47:02+02:00
  293. name: ticket
  294. passenger: !person
  295. first_name: Fabian Peter
  296. last_name: Hammerle
  297. price_brutto: !sum '1.23 EUR'
  298. ticket_url: https://www.example.com
  299. valid_from: 2016-07-14 13:50:04+01:05
  300. valid_until: 2016-07-14 18:50:04+00:00
  301. """],
  302. [get_shipping(), u"""!shipping
  303. destination_point: home
  304. price_brutto: !sum '1.23 EUR'
  305. """],
  306. [get_taxi_ride(), u"""!taxi-ride
  307. arrival_time: 2016-05-02 18:10:00+01:05
  308. departure_point: home
  309. departure_time: 2016-05-02 18:25:00+01:05
  310. destination_point: city
  311. distance: !distance '3.21 km'
  312. driver: driver
  313. name: taxi ride
  314. price_brutto: !sum '1.23 EUR'
  315. """],
  316. [get_invoice(), u"""!invoice
  317. creditor: platformπ
  318. debitor_id: customer
  319. invoice_date: 2016-05-08 00:18:17
  320. invoice_id: id
  321. items:
  322. - !item
  323. name: item a
  324. price_brutto: !sum '1.23 EUR'
  325. - !item
  326. name: item β
  327. price_brutto: !sum '20.45 EUR'
  328. """],
  329. ])
  330. def test_to_yaml(source_object, expected_yaml):
  331. assert expected_yaml == to_yaml(source_object)
  332. @pytest.mark.parametrize('expected_object,source_yaml', [
  333. [datetime.datetime(2016, 7, 14, 13, 50, 4, 0), '2016-07-14 13:50:04'],
  334. [datetime.datetime(2016, 7, 14, 13, 50, 4, 0, tzinfo = pytz.timezone('Europe/Vienna')), '2016-07-14 13:50:04+01:05'],
  335. [datetime.datetime(2016, 7, 14, 13, 50, 4, 0, tzinfo = pytz.utc), '2016-07-14 13:50:04+00:00'],
  336. [finoex.Distance(1.34, u'km'), u"!distance '1.34 km'\n"],
  337. [finoex.Distance(1.34, u'μm'), u"!distance '1.34 μm'"],
  338. [get_discount_a(), u"!discount\nname: discount a\namount: !sum '1.23 EUR'\n"],
  339. [get_discount_b(), u"!discount\nname: discount β\namount: !sum '20.45 EUR'\n"],
  340. [get_figure_a(), '!figure\nunit: km\nvalue: 12.3\n'],
  341. [get_figure_a(), u'!figure\nunit: km\nvalue: 12.3\n'],
  342. [get_figure_b(), '!figure\nunit: 米\nvalue: 12300\n'],
  343. [get_figure_b(), u'!figure\nunit: 米\nvalue: 12300\n'],
  344. [get_item_a(), u"!item\nname: item a\nprice_brutto: !sum '1.23 EUR'\n"],
  345. [get_item_a(), u"!item\nname: item a\nprice_brutto: !sum 1.23 EUR"],
  346. [get_item_a(), u"!item\nname: item a\nprice_brutto: !sum 1.23 €\n"],
  347. [get_item_b(), u"!item\nname: item β\nprice_brutto: !sum '20.45 EUR'\n"],
  348. [get_person_a(), '!person\nfirst_name: Fabian Peter\nlast_name: Hammerle\n'],
  349. [get_person_a(), u'!person\nfirst_name: Fabian Peter\nlast_name: Hammerle\n'],
  350. [get_person_b(), u'!person\nfirst_name: 名字\nlast_name: 贵姓\n'],
  351. [get_campaign_a(), u"""!campaign
  352. name: campaign a
  353. founder: company
  354. end: 2016-07-23 09:23:17+01:05
  355. """],
  356. [get_campaign_b(), u"""!campaign
  357. founder: company
  358. name: campaign without end
  359. website_url: http://campaign.com
  360. """],
  361. [get_service(), u"""!service
  362. duration: !duration
  363. years: 2
  364. name: service
  365. price_brutto: !sum '1.0 EUR'
  366. state: success
  367. """],
  368. [get_pledge(), u"""!pledge
  369. campaign: !campaign
  370. name: campaign a
  371. founder: company
  372. end: 2016-07-23 09:23:17+01:05
  373. price_brutto: !sum '10.0 EUR'
  374. reward: great
  375. """],
  376. [get_contribution(), u"""!contribution
  377. campaign: !campaign
  378. end: 2016-07-23 09:23:17+01:05
  379. founder: company
  380. name: campaign a
  381. price_brutto: !sum '10.0 EUR'
  382. reward: product
  383. """],
  384. [[get_person_a(), get_person_b()], u"""
  385. - !person
  386. first_name: Fabian Peter
  387. last_name: Hammerle
  388. - !person
  389. first_name: 名字
  390. last_name: 贵姓"""],
  391. [get_transportation(), u"""!transportation
  392. departure_point: home
  393. destination_point: city
  394. distance: !distance '3.21 km'
  395. name: ticket
  396. price_brutto: !sum '1.23 EUR'
  397. route_map: null
  398. passenger: !person
  399. first_name: Fabian Peter
  400. last_name: Hammerle
  401. ticket_url: https://www.example.com
  402. valid_from: 2016-07-14 13:50:04+01:05
  403. valid_until: 2016-07-14 18:50:04+00:00
  404. estimated_arrival_time: !period
  405. end: 2016-07-24T23:48:05+00:00
  406. start: 2016-07-24T23:47:02+02:00
  407. """],
  408. [get_shipping(), u"""!shipping
  409. destination_point: home
  410. price_brutto: !sum 1.23 EUR
  411. """],
  412. [get_order_a(), u"""!order
  413. customer_id: customer
  414. discounts:
  415. - !discount
  416. amount: !sum '1.23 EUR'
  417. name: discount a
  418. - !discount
  419. amount: !sum '20.45 EUR'
  420. name: discount β
  421. items:
  422. - !item
  423. name: item a
  424. price_brutto: !sum '1.23 EUR'
  425. - !item
  426. name: item β
  427. price_brutto: !sum '20.45 EUR'
  428. order_date: 2016-05-08 00:18:17
  429. order_id: id
  430. platform: platformπ
  431. """],
  432. [get_article(), u"""!article
  433. authors:
  434. - a
  435. - b
  436. delivery_date: null
  437. features: supergeil
  438. name: article name
  439. price_brutto: !sum '1.23 EUR'
  440. product_id: 0815
  441. quantity: 1
  442. reseller: seller
  443. shipper: shipper
  444. state: goood
  445. depth: !distance 12.3 dm
  446. height: !distance 123.0 cm
  447. maximum_load: !figure 40.0 kg
  448. width: !distance 1.23 m
  449. """],
  450. [get_taxi_ride(), u"""!taxi-ride
  451. arrival_time: 2016-05-02 18:10:00+01:05
  452. departure_point: home
  453. departure_time: 2016-05-02 18:25:00+01:05
  454. destination_point: city
  455. distance: !distance '3.21 km'
  456. driver: driver
  457. name: taxi ride
  458. price_brutto: !sum '1.23 EUR'
  459. route_map: null
  460. """],
  461. [get_invoice(), u"""!invoice
  462. creditor: platformπ
  463. debitor_id: customer
  464. invoice_date: 2016-05-08T00:18:17
  465. invoice_id: id
  466. items:
  467. - !item
  468. name: item a
  469. price_brutto: !sum '1.23 EUR'
  470. - !item
  471. name: item β
  472. price_brutto: !sum '20.45 EUR'
  473. """],
  474. ])
  475. def test_from_yaml(expected_object, source_yaml):
  476. class Loader(yaml.Loader):
  477. pass
  478. ioex.datetimeex.Duration.register_yaml_constructor(Loader)
  479. ioex.datetimeex.Period.register_yaml_constructor(Loader)
  480. ioex.calcex.Figure.register_yaml_constructor(Loader)
  481. finoex.Sum.register_yaml_constructor(Loader)
  482. finoex.Distance.register_yaml_constructor(Loader)
  483. loaded_object = yaml.load(source_yaml, Loader=Loader)
  484. assert loaded_object == expected_object