test_yaml.py 15 KB

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