test_yaml.py 15 KB

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