diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2018-01-17 02:43:28 +0100 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2018-01-17 02:43:28 +0100 |
commit | 183a53e3be74fabf501eaff19a39a47f1a6c9af5 (patch) | |
tree | 559ed084856dc99880bb6fd9d36933e5b65c172f | |
parent | dd359bc0617a915909efb2ef37048192c0639836 (diff) | |
download | Trader-183a53e3be74fabf501eaff19a39a47f1a6c9af5.tar.gz Trader-183a53e3be74fabf501eaff19a39a47f1a6c9af5.tar.zst Trader-183a53e3be74fabf501eaff19a39a47f1a6c9af5.zip |
Write some tests for Portfolio class
-rw-r--r-- | portfolio.py | 10 | ||||
-rw-r--r-- | test.py | 87 |
2 files changed, 92 insertions, 5 deletions
diff --git a/portfolio.py b/portfolio.py index 507f796..a4fbf94 100644 --- a/portfolio.py +++ b/portfolio.py | |||
@@ -32,8 +32,14 @@ class Portfolio: | |||
32 | urllib3.disable_warnings() | 32 | urllib3.disable_warnings() |
33 | http = urllib3.PoolManager() | 33 | http = urllib3.PoolManager() |
34 | 34 | ||
35 | r = http.request("GET", cls.URL) | 35 | try: |
36 | cls.data = json.loads(r.data) | 36 | r = http.request("GET", cls.URL) |
37 | except Exception: | ||
38 | return | ||
39 | try: | ||
40 | cls.data = json.loads(r.data) | ||
41 | except json.JSONDecodeError: | ||
42 | cls.data = None | ||
37 | 43 | ||
38 | @classmethod | 44 | @classmethod |
39 | def parse_cryptoportfolio(cls): | 45 | def parse_cryptoportfolio(cls): |
@@ -3,9 +3,6 @@ import unittest | |||
3 | from unittest import mock | 3 | from unittest import mock |
4 | 4 | ||
5 | class AmountTest(unittest.TestCase): | 5 | class AmountTest(unittest.TestCase): |
6 | def setUp(self): | ||
7 | super(AmountTest, self).setUp() | ||
8 | |||
9 | def test_values(self): | 6 | def test_values(self): |
10 | amount = portfolio.Amount("BTC", 0.65) | 7 | amount = portfolio.Amount("BTC", 0.65) |
11 | self.assertEqual(0.65, amount.value) | 8 | self.assertEqual(0.65, amount.value) |
@@ -170,5 +167,89 @@ class AmountTest(unittest.TestCase): | |||
170 | amount2.linked_to = amount3 | 167 | amount2.linked_to = amount3 |
171 | self.assertEqual("Amount(32.00000000 BTX -> Amount(12000.00000000 USDT -> Amount(0.10000000 BTC)))", repr(amount1)) | 168 | self.assertEqual("Amount(32.00000000 BTX -> Amount(12000.00000000 USDT -> Amount(0.10000000 BTC)))", repr(amount1)) |
172 | 169 | ||
170 | class PortfolioTest(unittest.TestCase): | ||
171 | import urllib3 | ||
172 | def fill_data(self): | ||
173 | if self.json_response is not None: | ||
174 | portfolio.Portfolio.data = self.json_response | ||
175 | |||
176 | def setUp(self): | ||
177 | super(PortfolioTest, self).setUp() | ||
178 | |||
179 | with open("test_portfolio.json") as example: | ||
180 | import json | ||
181 | self.json_response = json.load(example) | ||
182 | |||
183 | self.patcher = mock.patch.multiple(portfolio.Portfolio, data=None, liquidities={}) | ||
184 | self.patcher.start() | ||
185 | |||
186 | @mock.patch.object(urllib3, "disable_warnings") | ||
187 | @mock.patch.object(urllib3.poolmanager.PoolManager, "request") | ||
188 | @mock.patch.object(portfolio.Portfolio, "URL", new="foo://bar") | ||
189 | def test_get_cryptoportfolio(self, request, disable_warnings): | ||
190 | request.side_effect = [ | ||
191 | type('', (), { "data": '{ "foo": "bar" }' }), | ||
192 | type('', (), { "data": 'System Error' }), | ||
193 | Exception("Connection error"), | ||
194 | ] | ||
195 | |||
196 | portfolio.Portfolio.get_cryptoportfolio() | ||
197 | self.assertIn("foo", portfolio.Portfolio.data) | ||
198 | self.assertEqual("bar", portfolio.Portfolio.data["foo"]) | ||
199 | request.assert_called_with("GET", "foo://bar") | ||
200 | |||
201 | request.reset_mock() | ||
202 | portfolio.Portfolio.get_cryptoportfolio() | ||
203 | self.assertIsNone(portfolio.Portfolio.data) | ||
204 | request.assert_called_with("GET", "foo://bar") | ||
205 | |||
206 | request.reset_mock() | ||
207 | portfolio.Portfolio.data = "foo" | ||
208 | portfolio.Portfolio.get_cryptoportfolio() | ||
209 | request.assert_called_with("GET", "foo://bar") | ||
210 | self.assertEqual("foo", portfolio.Portfolio.data) | ||
211 | disable_warnings.assert_called_with() | ||
212 | |||
213 | @mock.patch.object(portfolio.Portfolio, "get_cryptoportfolio") | ||
214 | def test_parse_cryptoportfolio(self, mock_get): | ||
215 | mock_get.side_effect = self.fill_data | ||
216 | |||
217 | portfolio.Portfolio.parse_cryptoportfolio() | ||
218 | |||
219 | self.assertListEqual( | ||
220 | ["medium", "high"], | ||
221 | list(portfolio.Portfolio.liquidities.keys())) | ||
222 | |||
223 | liquidities = portfolio.Portfolio.liquidities | ||
224 | self.assertEqual(10, len(liquidities["medium"].keys())) | ||
225 | self.assertEqual(10, len(liquidities["high"].keys())) | ||
226 | |||
227 | expected = {'BTC': 2857, 'DGB': 1015, 'DOGE': 1805, 'SC': 623, 'ZEC': 3701} | ||
228 | self.assertDictEqual(expected, liquidities["high"]['2018-01-08']) | ||
229 | |||
230 | expected = {'ETC': 1000, 'FCT': 1000, 'GAS': 1000, 'NAV': 1000, 'OMG': 1000, 'OMNI': 1000, 'PPC': 1000, 'RIC': 1000, 'VIA': 1000, 'XCP': 1000} | ||
231 | self.assertDictEqual(expected, liquidities["medium"]['2018-01-08']) | ||
232 | |||
233 | # It doesn't refetch the data when available | ||
234 | portfolio.Portfolio.parse_cryptoportfolio() | ||
235 | mock_get.assert_called_once_with() | ||
236 | |||
237 | portfolio.Portfolio.data["portfolio_1"]["holding"]["direction"][3] = "short" | ||
238 | self.assertRaises(AssertionError, portfolio.Portfolio.parse_cryptoportfolio) | ||
239 | |||
240 | @mock.patch.object(portfolio.Portfolio, "get_cryptoportfolio") | ||
241 | def test_repartition_pertenthousand(self, mock_get): | ||
242 | mock_get.side_effect = self.fill_data | ||
243 | |||
244 | expected_medium = {'USDT': 1000, 'ETC': 1000, 'FCT': 1000, 'OMG': 1000, 'STEEM': 1000, 'STRAT': 1000, 'XEM': 1000, 'XMR': 1000, 'XVC': 1000, 'ZRX': 1000} | ||
245 | expected_high = {'USDT': 1226, 'BTC': 1429, 'ETC': 1127, 'ETH': 1569, 'FCT': 3341, 'GAS': 1308} | ||
246 | |||
247 | self.assertEqual(expected_medium, portfolio.Portfolio.repartition_pertenthousand()) | ||
248 | self.assertEqual(expected_medium, portfolio.Portfolio.repartition_pertenthousand(liquidity="medium")) | ||
249 | self.assertEqual(expected_high, portfolio.Portfolio.repartition_pertenthousand(liquidity="high")) | ||
250 | |||
251 | def tearDown(self): | ||
252 | self.patcher.stop() | ||
253 | |||
173 | if __name__ == '__main__': | 254 | if __name__ == '__main__': |
174 | unittest.main() | 255 | unittest.main() |