aboutsummaryrefslogtreecommitdiff
path: root/test.py
diff options
context:
space:
mode:
Diffstat (limited to 'test.py')
-rw-r--r--test.py203
1 files changed, 92 insertions, 111 deletions
diff --git a/test.py b/test.py
index bbe0697..d4432f6 100644
--- a/test.py
+++ b/test.py
@@ -7,7 +7,7 @@ from unittest import mock
7import requests 7import requests
8import requests_mock 8import requests_mock
9from io import StringIO 9from io import StringIO
10import portfolio, market, main 10import portfolio, market, main, store
11 11
12limits = ["acceptance", "unit"] 12limits = ["acceptance", "unit"]
13for test_type in limits: 13for test_type in limits:
@@ -32,7 +32,11 @@ class WebMockTestCase(unittest.TestCase):
32 self.m.debug = False 32 self.m.debug = False
33 33
34 self.patchers = [ 34 self.patchers = [
35 mock.patch.multiple(portfolio.Portfolio, last_date=None, data=None, liquidities={}), 35 mock.patch.multiple(market.Portfolio,
36 last_date=None,
37 data=None,
38 liquidities={},
39 report=mock.Mock()),
36 mock.patch.multiple(portfolio.Computation, 40 mock.patch.multiple(portfolio.Computation,
37 computations=portfolio.Computation.computations), 41 computations=portfolio.Computation.computations),
38 ] 42 ]
@@ -439,57 +443,64 @@ class poloniexETest(unittest.TestCase):
439 443
440@unittest.skipUnless("unit" in limits, "Unit skipped") 444@unittest.skipUnless("unit" in limits, "Unit skipped")
441class PortfolioTest(WebMockTestCase): 445class PortfolioTest(WebMockTestCase):
442 def fill_data(self):
443 if self.json_response is not None:
444 portfolio.Portfolio.data = self.json_response
445
446 def setUp(self): 446 def setUp(self):
447 super(PortfolioTest, self).setUp() 447 super(PortfolioTest, self).setUp()
448 448
449 with open("test_samples/test_portfolio.json") as example: 449 with open("test_samples/test_portfolio.json") as example:
450 self.json_response = example.read() 450 self.json_response = example.read()
451 451
452 self.wm.get(portfolio.Portfolio.URL, text=self.json_response) 452 self.wm.get(market.Portfolio.URL, text=self.json_response)
453 453
454 def test_get_cryptoportfolio(self): 454 @mock.patch.object(market.Portfolio, "parse_cryptoportfolio")
455 self.wm.get(portfolio.Portfolio.URL, [ 455 def test_get_cryptoportfolio(self, parse_cryptoportfolio):
456 self.wm.get(market.Portfolio.URL, [
456 {"text":'{ "foo": "bar" }', "status_code": 200}, 457 {"text":'{ "foo": "bar" }', "status_code": 200},
457 {"text": "System Error", "status_code": 500}, 458 {"text": "System Error", "status_code": 500},
458 {"exc": requests.exceptions.ConnectTimeout}, 459 {"exc": requests.exceptions.ConnectTimeout},
459 ]) 460 ])
460 portfolio.Portfolio.get_cryptoportfolio(self.m) 461 market.Portfolio.get_cryptoportfolio()
461 self.assertIn("foo", portfolio.Portfolio.data) 462 self.assertIn("foo", market.Portfolio.data)
462 self.assertEqual("bar", portfolio.Portfolio.data["foo"]) 463 self.assertEqual("bar", market.Portfolio.data["foo"])
463 self.assertTrue(self.wm.called) 464 self.assertTrue(self.wm.called)
464 self.assertEqual(1, self.wm.call_count) 465 self.assertEqual(1, self.wm.call_count)
465 self.m.report.log_error.assert_not_called() 466 market.Portfolio.report.log_error.assert_not_called()
466 self.m.report.log_http_request.assert_called_once() 467 market.Portfolio.report.log_http_request.assert_called_once()
467 self.m.report.log_http_request.reset_mock() 468 parse_cryptoportfolio.assert_called_once_with()
468 469 market.Portfolio.report.log_http_request.reset_mock()
469 portfolio.Portfolio.get_cryptoportfolio(self.m) 470 parse_cryptoportfolio.reset_mock()
470 self.assertIsNone(portfolio.Portfolio.data) 471 market.Portfolio.data = None
472
473 market.Portfolio.get_cryptoportfolio()
474 self.assertIsNone(market.Portfolio.data)
471 self.assertEqual(2, self.wm.call_count) 475 self.assertEqual(2, self.wm.call_count)
472 self.m.report.log_error.assert_not_called() 476 parse_cryptoportfolio.assert_not_called()
473 self.m.report.log_http_request.assert_called_once() 477 market.Portfolio.report.log_error.assert_not_called()
474 self.m.report.log_http_request.reset_mock() 478 market.Portfolio.report.log_http_request.assert_called_once()
475 479 market.Portfolio.report.log_http_request.reset_mock()
480 parse_cryptoportfolio.reset_mock()
481
482 market.Portfolio.data = "Foo"
483 market.Portfolio.get_cryptoportfolio()
484 self.assertEqual(2, self.wm.call_count)
485 parse_cryptoportfolio.assert_not_called()
476 486
477 portfolio.Portfolio.data = "Foo" 487 market.Portfolio.get_cryptoportfolio(refetch=True)
478 portfolio.Portfolio.get_cryptoportfolio(self.m) 488 self.assertEqual("Foo", market.Portfolio.data)
479 self.assertEqual("Foo", portfolio.Portfolio.data)
480 self.assertEqual(3, self.wm.call_count) 489 self.assertEqual(3, self.wm.call_count)
481 self.m.report.log_error.assert_called_once_with("get_cryptoportfolio", 490 market.Portfolio.report.log_error.assert_called_once_with("get_cryptoportfolio",
482 exception=mock.ANY) 491 exception=mock.ANY)
483 self.m.report.log_http_request.assert_not_called() 492 market.Portfolio.report.log_http_request.assert_not_called()
484 493
485 def test_parse_cryptoportfolio(self): 494 def test_parse_cryptoportfolio(self):
486 portfolio.Portfolio.parse_cryptoportfolio(self.m) 495 market.Portfolio.data = store.json.loads(self.json_response, parse_int=D,
496 parse_float=D)
497 market.Portfolio.parse_cryptoportfolio()
487 498
488 self.assertListEqual( 499 self.assertListEqual(
489 ["medium", "high"], 500 ["medium", "high"],
490 list(portfolio.Portfolio.liquidities.keys())) 501 list(market.Portfolio.liquidities.keys()))
491 502
492 liquidities = portfolio.Portfolio.liquidities 503 liquidities = market.Portfolio.liquidities
493 self.assertEqual(10, len(liquidities["medium"].keys())) 504 self.assertEqual(10, len(liquidities["medium"].keys()))
494 self.assertEqual(10, len(liquidities["high"].keys())) 505 self.assertEqual(10, len(liquidities["high"].keys()))
495 506
@@ -517,94 +528,64 @@ class PortfolioTest(WebMockTestCase):
517 'XCP': (D("0.1"), "long"), 528 'XCP': (D("0.1"), "long"),
518 } 529 }
519 self.assertDictEqual(expected, liquidities["medium"][date]) 530 self.assertDictEqual(expected, liquidities["medium"][date])
520 self.assertEqual(portfolio.datetime(2018, 1, 15), portfolio.Portfolio.last_date) 531 self.assertEqual(portfolio.datetime(2018, 1, 15), market.Portfolio.last_date)
521 532
522 self.m.report.log_http_request.assert_called_once_with("GET", 533 @mock.patch.object(market.Portfolio, "get_cryptoportfolio")
523 portfolio.Portfolio.URL, None, mock.ANY, mock.ANY) 534 def test_repartition(self, get_cryptoportfolio):
524 self.m.report.log_http_request.reset_mock() 535 market.Portfolio.liquidities = {
525 536 "medium": {
526 # It doesn't refetch the data when available 537 "2018-03-01": "medium_2018-03-01",
527 portfolio.Portfolio.parse_cryptoportfolio(self.m) 538 "2018-03-08": "medium_2018-03-08",
528 self.m.report.log_http_request.assert_not_called() 539 },
529 540 "high": {
530 self.assertEqual(1, self.wm.call_count) 541 "2018-03-01": "high_2018-03-01",
531 542 "2018-03-08": "high_2018-03-08",
532 portfolio.Portfolio.parse_cryptoportfolio(self.m, refetch=True) 543 }
533 self.assertEqual(2, self.wm.call_count)
534 self.m.report.log_http_request.assert_called_once()
535
536 def test_repartition(self):
537 expected_medium = {
538 'BTC': (D("1.1102e-16"), "long"),
539 'USDT': (D("0.1"), "long"),
540 'ETC': (D("0.1"), "long"),
541 'FCT': (D("0.1"), "long"),
542 'OMG': (D("0.1"), "long"),
543 'STEEM': (D("0.1"), "long"),
544 'STRAT': (D("0.1"), "long"),
545 'XEM': (D("0.1"), "long"),
546 'XMR': (D("0.1"), "long"),
547 'XVC': (D("0.1"), "long"),
548 'ZRX': (D("0.1"), "long"),
549 }
550 expected_high = {
551 'USDT': (D("0.1226"), "long"),
552 'BTC': (D("0.1429"), "long"),
553 'ETC': (D("0.1127"), "long"),
554 'ETH': (D("0.1569"), "long"),
555 'FCT': (D("0.3341"), "long"),
556 'GAS': (D("0.1308"), "long"),
557 } 544 }
545 market.Portfolio.last_date = "2018-03-08"
558 546
559 self.assertEqual(expected_medium, portfolio.Portfolio.repartition(self.m)) 547 self.assertEqual("medium_2018-03-08", market.Portfolio.repartition())
560 self.assertEqual(expected_medium, portfolio.Portfolio.repartition(self.m, liquidity="medium")) 548 get_cryptoportfolio.assert_called_once_with()
561 self.assertEqual(expected_high, portfolio.Portfolio.repartition(self.m, liquidity="high")) 549 self.assertEqual("medium_2018-03-08", market.Portfolio.repartition(liquidity="medium"))
562 550 self.assertEqual("high_2018-03-08", market.Portfolio.repartition(liquidity="high"))
563 self.assertEqual(1, self.wm.call_count)
564
565 portfolio.Portfolio.repartition(self.m)
566 self.assertEqual(1, self.wm.call_count)
567
568 portfolio.Portfolio.repartition(self.m, refetch=True)
569 self.assertEqual(2, self.wm.call_count)
570 self.m.report.log_http_request.assert_called()
571 self.assertEqual(2, self.m.report.log_http_request.call_count)
572 551
573 @mock.patch.object(portfolio.time, "sleep") 552 @mock.patch.object(market.time, "sleep")
574 @mock.patch.object(portfolio.Portfolio, "repartition") 553 @mock.patch.object(market.Portfolio, "get_cryptoportfolio")
575 def test_wait_for_recent(self, repartition, sleep): 554 def test_wait_for_recent(self, get_cryptoportfolio, sleep):
576 self.call_count = 0 555 self.call_count = 0
577 def _repartition(market, refetch): 556 def _get(refetch=False):
578 self.assertEqual(self.m, market) 557 if self.call_count != 0:
579 self.assertTrue(refetch) 558 self.assertTrue(refetch)
559 else:
560 self.assertFalse(refetch)
580 self.call_count += 1 561 self.call_count += 1
581 portfolio.Portfolio.last_date = portfolio.datetime.now()\ 562 market.Portfolio.last_date = store.datetime.now()\
582 - portfolio.timedelta(10)\ 563 - store.timedelta(10)\
583 + portfolio.timedelta(self.call_count) 564 + store.timedelta(self.call_count)
584 repartition.side_effect = _repartition 565 get_cryptoportfolio.side_effect = _get
585 566
586 portfolio.Portfolio.wait_for_recent(self.m) 567 market.Portfolio.wait_for_recent()
587 sleep.assert_called_with(30) 568 sleep.assert_called_with(30)
588 self.assertEqual(6, sleep.call_count) 569 self.assertEqual(6, sleep.call_count)
589 self.assertEqual(7, repartition.call_count) 570 self.assertEqual(7, get_cryptoportfolio.call_count)
590 self.m.report.print_log.assert_called_with("Attempt to fetch up-to-date cryptoportfolio") 571 market.Portfolio.report.print_log.assert_called_with("Attempt to fetch up-to-date cryptoportfolio")
591 572
592 sleep.reset_mock() 573 sleep.reset_mock()
593 repartition.reset_mock() 574 get_cryptoportfolio.reset_mock()
594 portfolio.Portfolio.last_date = None 575 market.Portfolio.last_date = None
595 self.call_count = 0 576 self.call_count = 0
596 portfolio.Portfolio.wait_for_recent(self.m, delta=15) 577 market.Portfolio.wait_for_recent(delta=15)
597 sleep.assert_not_called() 578 sleep.assert_not_called()
598 self.assertEqual(1, repartition.call_count) 579 self.assertEqual(1, get_cryptoportfolio.call_count)
599 580
600 sleep.reset_mock() 581 sleep.reset_mock()
601 repartition.reset_mock() 582 get_cryptoportfolio.reset_mock()
602 portfolio.Portfolio.last_date = None 583 market.Portfolio.last_date = None
603 self.call_count = 0 584 self.call_count = 0
604 portfolio.Portfolio.wait_for_recent(self.m, delta=1) 585 market.Portfolio.wait_for_recent(delta=1)
605 sleep.assert_called_with(30) 586 sleep.assert_called_with(30)
606 self.assertEqual(9, sleep.call_count) 587 self.assertEqual(9, sleep.call_count)
607 self.assertEqual(10, repartition.call_count) 588 self.assertEqual(10, get_cryptoportfolio.call_count)
608 589
609@unittest.skipUnless("unit" in limits, "Unit skipped") 590@unittest.skipUnless("unit" in limits, "Unit skipped")
610class AmountTest(WebMockTestCase): 591class AmountTest(WebMockTestCase):
@@ -1047,7 +1028,7 @@ class MarketTest(WebMockTestCase):
1047 self.assertEqual("Foo", m.fetch_fees()) 1028 self.assertEqual("Foo", m.fetch_fees())
1048 self.ccxt.fetch_fees.assert_not_called() 1029 self.ccxt.fetch_fees.assert_not_called()
1049 1030
1050 @mock.patch.object(portfolio.Portfolio, "repartition") 1031 @mock.patch.object(market.Portfolio, "repartition")
1051 @mock.patch.object(market.Market, "get_ticker") 1032 @mock.patch.object(market.Market, "get_ticker")
1052 @mock.patch.object(market.TradeStore, "compute_trades") 1033 @mock.patch.object(market.TradeStore, "compute_trades")
1053 def test_prepare_trades(self, compute_trades, get_ticker, repartition): 1034 def test_prepare_trades(self, compute_trades, get_ticker, repartition):
@@ -1098,7 +1079,7 @@ class MarketTest(WebMockTestCase):
1098 m.report.log_balances.assert_called_once_with(tag="tag") 1079 m.report.log_balances.assert_called_once_with(tag="tag")
1099 1080
1100 1081
1101 @mock.patch.object(portfolio.time, "sleep") 1082 @mock.patch.object(market.time, "sleep")
1102 @mock.patch.object(market.TradeStore, "all_orders") 1083 @mock.patch.object(market.TradeStore, "all_orders")
1103 def test_follow_orders(self, all_orders, time_mock): 1084 def test_follow_orders(self, all_orders, time_mock):
1104 for debug, sleep in [ 1085 for debug, sleep in [
@@ -1693,7 +1674,7 @@ class BalanceStoreTest(WebMockTestCase):
1693 self.assertListEqual(["USDT", "XVG", "XMR", "ETC"], list(balance_store.currencies())) 1674 self.assertListEqual(["USDT", "XVG", "XMR", "ETC"], list(balance_store.currencies()))
1694 self.m.report.log_balances.assert_called_with(tag="foo") 1675 self.m.report.log_balances.assert_called_with(tag="foo")
1695 1676
1696 @mock.patch.object(portfolio.Portfolio, "repartition") 1677 @mock.patch.object(market.Portfolio, "repartition")
1697 def test_dispatch_assets(self, repartition): 1678 def test_dispatch_assets(self, repartition):
1698 self.m.ccxt.fetch_all_balances.return_value = self.fetch_balance 1679 self.m.ccxt.fetch_all_balances.return_value = self.fetch_balance
1699 1680
@@ -1710,7 +1691,7 @@ class BalanceStoreTest(WebMockTestCase):
1710 repartition.return_value = repartition_hash 1691 repartition.return_value = repartition_hash
1711 1692
1712 amounts = balance_store.dispatch_assets(portfolio.Amount("BTC", "11.1")) 1693 amounts = balance_store.dispatch_assets(portfolio.Amount("BTC", "11.1"))
1713 repartition.assert_called_with(self.m, liquidity="medium") 1694 repartition.assert_called_with(liquidity="medium")
1714 self.assertIn("XEM", balance_store.currencies()) 1695 self.assertIn("XEM", balance_store.currencies())
1715 self.assertEqual(D("2.6"), amounts["BTC"].value) 1696 self.assertEqual(D("2.6"), amounts["BTC"].value)
1716 self.assertEqual(D("7.5"), amounts["XEM"].value) 1697 self.assertEqual(D("7.5"), amounts["XEM"].value)
@@ -3505,7 +3486,7 @@ class ProcessorTest(WebMockTestCase):
3505 3486
3506 processor.run_action("wait_for_recent", "bar", "baz") 3487 processor.run_action("wait_for_recent", "bar", "baz")
3507 3488
3508 method_mock.assert_called_with(self.m, foo="bar") 3489 method_mock.assert_called_with(foo="bar")
3509 3490
3510 def test_select_step(self): 3491 def test_select_step(self):
3511 processor = market.Processor(self.m) 3492 processor = market.Processor(self.m)
@@ -3547,7 +3528,7 @@ class ProcessorTest(WebMockTestCase):
3547 processor = market.Processor(m) 3528 processor = market.Processor(m)
3548 3529
3549 method, arguments = processor.method_arguments("wait_for_recent") 3530 method, arguments = processor.method_arguments("wait_for_recent")
3550 self.assertEqual(portfolio.Portfolio.wait_for_recent, method) 3531 self.assertEqual(market.Portfolio.wait_for_recent, method)
3551 self.assertEqual(["delta"], arguments) 3532 self.assertEqual(["delta"], arguments)
3552 3533
3553 method, arguments = processor.method_arguments("prepare_trades") 3534 method, arguments = processor.method_arguments("prepare_trades")
@@ -3730,7 +3711,7 @@ class AcceptanceTest(WebMockTestCase):
3730 market = mock.Mock() 3711 market = mock.Mock()
3731 market.fetch_all_balances.return_value = fetch_balance 3712 market.fetch_all_balances.return_value = fetch_balance
3732 market.fetch_ticker.side_effect = fetch_ticker 3713 market.fetch_ticker.side_effect = fetch_ticker
3733 with mock.patch.object(portfolio.Portfolio, "repartition", return_value=repartition): 3714 with mock.patch.object(market.Portfolio, "repartition", return_value=repartition):
3734 # Action 1 3715 # Action 1
3735 helper.prepare_trades(market) 3716 helper.prepare_trades(market)
3736 3717
@@ -3809,7 +3790,7 @@ class AcceptanceTest(WebMockTestCase):
3809 "amount": "10", "total": "1" 3790 "amount": "10", "total": "1"
3810 } 3791 }
3811 ] 3792 ]
3812 with mock.patch.object(portfolio.time, "sleep") as sleep: 3793 with mock.patch.object(market.time, "sleep") as sleep:
3813 # Action 4 3794 # Action 4
3814 helper.follow_orders(verbose=False) 3795 helper.follow_orders(verbose=False)
3815 3796
@@ -3850,7 +3831,7 @@ class AcceptanceTest(WebMockTestCase):
3850 } 3831 }
3851 market.fetch_all_balances.return_value = fetch_balance 3832 market.fetch_all_balances.return_value = fetch_balance
3852 3833
3853 with mock.patch.object(portfolio.Portfolio, "repartition", return_value=repartition): 3834 with mock.patch.object(market.Portfolio, "repartition", return_value=repartition):
3854 # Action 5 3835 # Action 5
3855 helper.prepare_trades(market, only="acquire", compute_value="average") 3836 helper.prepare_trades(market, only="acquire", compute_value="average")
3856 3837
@@ -3922,7 +3903,7 @@ class AcceptanceTest(WebMockTestCase):
3922 # TODO 3903 # TODO
3923 # portfolio.TradeStore.run_orders() 3904 # portfolio.TradeStore.run_orders()
3924 3905
3925 with mock.patch.object(portfolio.time, "sleep") as sleep: 3906 with mock.patch.object(market.time, "sleep") as sleep:
3926 # Action 8 3907 # Action 8
3927 helper.follow_orders(verbose=False) 3908 helper.follow_orders(verbose=False)
3928 3909