Repository: lagerfeuer/cryptocompare

Issue:
Improve testing (add unit tests)
Add unit tests to give a better testing experience when developing the library.

Discussion:

Patch:
diff --git a/.gitignore b/.gitignore
index e83d033..7bbc71c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,3 @@
-.vscode/
 # Byte-compiled / optimized / DLL files
 __pycache__/
 *.py[cod]
diff --git a/README.rst b/README.rst
index c56a560..6d11bfb 100644
--- a/README.rst
+++ b/README.rst
@@ -8,7 +8,7 @@ Installation
 
 .. code:: bash
    
-   sudo pip3 install cryptocompare
+   pip3 install cryptocompare
 
 Usage
 *****
@@ -49,7 +49,8 @@ Coin List
    # },
    # ...
 
-If ``format`` is ``True``, the coin list is returned as Python list.
+If ``format`` is ``True``, the coin list is returned as Python list,
+containing only the abbreviations (like `BTC`).
 
 Price
 -----
@@ -131,6 +132,17 @@ Exchanges
    cryptocompare.get_exchanges()
 
 
+Developing
+**********
+
+Install the dependencies and run the tests with:
+
+.. code:: shell
+
+    pip3 install -r requirements.txt
+    python3 -m pytest
+
+
 Credit
 ******
 
diff --git a/cryptocompare/cryptocompare.py b/cryptocompare/cryptocompare.py
index a013cd9..4950579 100644
--- a/cryptocompare/cryptocompare.py
+++ b/cryptocompare/cryptocompare.py
@@ -72,13 +72,19 @@ def get_historical_price(coin, curr=CURR, timestamp=time.time(), exchange='CCCAG
         int(timestamp), format_parameter(exchange)))
 
 def get_historical_price_day(coin, curr=CURR, limit=LIMIT):
-    return query_cryptocompare(URL_HIST_PRICE_DAY.format(coin, format_parameter(curr), limit))
+    response = query_cryptocompare(URL_HIST_PRICE_DAY.format(coin, format_parameter(curr), limit))
+    if response:
+        return response['Data']
 
 def get_historical_price_hour(coin, curr=CURR, limit=LIMIT):
-    return query_cryptocompare(URL_HIST_PRICE_HOUR.format(coin, format_parameter(curr), limit))
+    response = query_cryptocompare(URL_HIST_PRICE_HOUR.format(coin, format_parameter(curr), limit))
+    if response:
+        return response['Data']
 
 def get_historical_price_minute(coin, curr=CURR, limit=LIMIT):
-    return query_cryptocompare(URL_HIST_PRICE_MINUTE.format(coin, format_parameter(curr), limit))
+    response = query_cryptocompare(URL_HIST_PRICE_MINUTE.format(coin, format_parameter(curr), limit))
+    if response:
+        return response['Data']
 
 def get_avg(coin, curr=CURR, exchange='CCCAGG'):
     response = query_cryptocompare(URL_AVG.format(coin, curr, format_parameter(exchange)))
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..dfcc200
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,29 @@
+astroid==2.3.3
+attrs==19.3.0
+autopep8==1.5
+certifi==2019.11.28
+chardet==3.0.4
+coverage==5.0.3
+doc8==0.8.0
+docutils==0.16
+idna==2.8
+isort==4.3.21
+lazy-object-proxy==1.4.3
+mccabe==0.6.1
+more-itertools==8.1.0
+packaging==20.1
+pbr==5.4.4
+pluggy==0.13.1
+py==1.8.1
+pycodestyle==2.5.0
+pylint==2.4.4
+pyparsing==2.4.6
+pytest==5.3.4
+pytest-cov==2.8.1
+requests==2.22.0
+restructuredtext-lint==1.3.0
+six==1.14.0
+stevedore==1.31.0
+urllib3==1.25.8
+wcwidth==0.1.8
+wrapt==1.11.2


Test patch:
diff --git a/test.py b/test.py
deleted file mode 100755
index c9c25d0..0000000
--- a/test.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python
-
-import cryptocompare
-import datetime
-import time
-
-coins = ['BTC', 'ETH', 'XMR', 'NEO']
-currencies = ['EUR', 'USD', 'GBP']
-limit = 500
-
-print('================== COIN LIST =====================')
-print(cryptocompare.get_coin_list())
-print(cryptocompare.get_coin_list(True))
-
-print('===================== PRICE ======================')
-print(cryptocompare.get_price(coins[0]))
-print(cryptocompare.get_price(coins[1], curr='USD'))
-print(cryptocompare.get_price(coins[2], curr=['EUR','USD','GBP']))
-print(cryptocompare.get_price(coins[2], full=True))
-print(cryptocompare.get_price(coins[0], curr='USD', full=True))
-print(cryptocompare.get_price(coins[1], curr=['EUR','USD','GBP'], full=True))
-
-print('==================================================')
-print(cryptocompare.get_price(coins))
-print(cryptocompare.get_price(coins, curr='USD'))
-print(cryptocompare.get_price(coins, curr=['EUR','USD','GBP']))
-
-print('==================== HIST PRICE ==================')
-print(cryptocompare.get_historical_price(coins[0]))
-print(cryptocompare.get_historical_price(coins[0], curr='USD'))
-print(cryptocompare.get_historical_price(coins[1], curr=['EUR','USD','GBP']))
-print(cryptocompare.get_historical_price(coins[1], 'USD', datetime.datetime.now()))
-print(cryptocompare.get_historical_price(coins[2], ['EUR','USD','GBP'], time.time(), exchange='Kraken'))
-
-print('================== HIST PRICE MINUTE ===============')
-print(cryptocompare.get_historical_price_minute(coins[0], curr='USD'))
-print(cryptocompare.get_historical_price_minute(coins[0], curr='USD', limit=100))
-
-print('================== HIST PRICE HOUR ===============')
-print(cryptocompare.get_historical_price_hour(coins[0]))
-print(cryptocompare.get_historical_price_hour(coins[0], curr='USD'))
-print(cryptocompare.get_historical_price_hour(coins[1], curr=['EUR','USD','GBP']))
-
-print('================== HIST PRICE DAY ================')
-print(cryptocompare.get_historical_price_day(coins[0]))
-print(cryptocompare.get_historical_price_day(coins[0], curr='USD'))
-print(cryptocompare.get_historical_price_day(coins[1], curr=['EUR','USD','GBP']))
-
-print('======================== AVG =====================')
-print(cryptocompare.get_avg(coins[0], exchange='Coinbase'))
-print(cryptocompare.get_avg(coins[0], curr='USD', exchange='Coinbase'))
-
-print('====================== EXCHANGES =================')
-print(cryptocompare.get_exchanges())
diff --git a/test/test_cryptocompare.py b/test/test_cryptocompare.py
new file mode 100644
index 0000000..4a8cc2a
--- /dev/null
+++ b/test/test_cryptocompare.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python3
+
+import unittest
+import cryptocompare
+import datetime
+
+class TestCryptoCompare(unittest.TestCase):
+  def assertCoinAndCurrInPrice(self, coin, curr, price):
+    if isinstance(coin, list):
+      for co in coin:
+        self.assertCoinAndCurrInPrice(co, curr, price)
+      return
+    else:
+      self.assertIn(coin, price)
+
+    if isinstance(curr, list):
+      for cu in curr:
+        self.assertIn(cu, price[coin])
+    else:
+      self.assertIn(curr, price[coin])
+
+  def test_coin_list(self):
+    lst = cryptocompare.get_coin_list()
+    self.assertTrue('BTC' in lst.keys())
+    lst = cryptocompare.get_coin_list(True)
+    self.assertTrue('BTC' in lst)
+
+  def test_get_price(self):
+    coin = 'BTC'
+    price = cryptocompare.get_price(coin)
+    self.assertCoinAndCurrInPrice(coin, 'EUR', price)
+    price = cryptocompare.get_price(coin, curr='USD')
+    self.assertCoinAndCurrInPrice(coin, 'USD', price)
+    currencies = ['EUR','USD','GBP']
+    price = cryptocompare.get_price(coin, curr=currencies)
+    self.assertCoinAndCurrInPrice(coin, currencies, price)
+    coins = ['BTC', 'XMR']
+    price = cryptocompare.get_price(coins, curr=currencies)
+    self.assertCoinAndCurrInPrice(coins, currencies, price)
+
+  def test_get_price_full(self):
+    price = cryptocompare.get_price('ETH', full=True)
+    self.assertIn('RAW', price)
+    self.assertIn('ETH', price['RAW'])
+    self.assertIn('EUR', price['RAW']['ETH'])
+    self.assertIn('PRICE', price['RAW']['ETH']['EUR'])
+
+  def test_get_historical_price(self):
+    coin = 'XMR'
+    curr = 'EUR'
+    price = cryptocompare.get_historical_price('XMR', timestamp=datetime.datetime(2017,6,6), exchange='CCCAGG')
+    self.assertCoinAndCurrInPrice(coin, curr, price)
+    price2 = cryptocompare.get_historical_price('XMR', 'EUR', datetime.datetime(2017,6,6))
+    self.assertCoinAndCurrInPrice(coin, curr, price2)
+    self.assertEqual(price, price2)
+
+  def test_price_day(self):
+    coin = 'BTC'
+    curr = 'USD'
+    price = cryptocompare.get_historical_price_day(coin, curr=curr, limit=3)
+    for frame in price:
+      self.assertIn('time', frame)
+
+  def test_price_hour(self):
+    coin = 'BTC'
+    curr = 'USD'
+    price = cryptocompare.get_historical_price_hour(coin, curr=curr, limit=3)
+    for frame in price:
+      self.assertIn('time', frame)
+
+  def test_price_minute(self):
+    coin = 'BTC'
+    curr = 'USD'
+    price = cryptocompare.get_historical_price_minute(coin, curr=curr, limit=3)
+    for frame in price:
+      self.assertIn('time', frame)
+
+  def test_get_avg(self):
+    coin = 'BTC'
+    curr = 'USD'
+    avg = cryptocompare.get_avg(coin, curr, exchange='Kraken')
+    self.assertEqual(avg['LASTMARKET'], 'Kraken')
+    self.assertEqual(avg['FROMSYMBOL'], coin)
+    self.assertEqual(avg['TOSYMBOL'], curr)
+
+  def test_get_exchanges(self):
+    exchanges = cryptocompare.get_exchanges()
+    self.assertIn('Kraken', exchanges)
+
+if __name__ == "__main__":
+  unittest.main()
\ No newline at end of file