stable/freqtrade/tests/test_misc.py
kryofly 508a20e849 test misc
Tests for functions common_datearray and test_scripts_options
2018-02-11 13:34:39 +01:00

239 lines
6.8 KiB
Python

# pragma pylint: disable=missing-docstring,C0103
import argparse
import json
import time
import datetime
import pytest
import numpy as np
import pandas as pd
from copy import deepcopy
from unittest.mock import MagicMock
from jsonschema import ValidationError
from freqtrade.analyze import parse_ticker_dataframe
from freqtrade.misc import (common_args_parser, file_dump_json, load_config,
parse_args, parse_timerange, throttle, datesarray_to_datetimearray)
import freqtrade.misc as misc
def test_throttle():
def func():
return 42
start = time.time()
result = throttle(func, min_secs=0.1)
end = time.time()
assert result == 42
assert end - start > 0.1
result = throttle(func, min_secs=-1)
assert result == 42
def test_throttle_with_assets():
def func(nb_assets=-1):
return nb_assets
result = throttle(func, min_secs=0.1, nb_assets=666)
assert result == 666
result = throttle(func, min_secs=0.1)
assert result == -1
# Parse common command-line-arguments. Used for all tools
def test_parse_args_none():
args = common_args_parser('')
assert isinstance(args, argparse.ArgumentParser)
def test_parse_args_defaults():
args = parse_args([], '')
assert args.config == 'config.json'
assert args.dynamic_whitelist is None
assert args.loglevel == 20
def test_parse_args_config():
args = parse_args(['-c', '/dev/null'], '')
assert args.config == '/dev/null'
args = parse_args(['--config', '/dev/null'], '')
assert args.config == '/dev/null'
def test_parse_args_verbose():
args = parse_args(['-v'], '')
assert args.loglevel == 10
args = parse_args(['--verbose'], '')
assert args.loglevel == 10
def test_parse_args_version():
with pytest.raises(SystemExit, match=r'0'):
parse_args(['--version'], '')
def test_parse_args_invalid():
with pytest.raises(SystemExit, match=r'2'):
parse_args(['-c'], '')
# Parse command-line-arguments
# used for main, backtesting and hyperopt
def test_parse_args_dynamic_whitelist():
args = parse_args(['--dynamic-whitelist'], '')
assert args.dynamic_whitelist == 20
def test_parse_args_dynamic_whitelist_10():
args = parse_args(['--dynamic-whitelist', '10'], '')
assert args.dynamic_whitelist == 10
def test_parse_args_dynamic_whitelist_invalid_values():
with pytest.raises(SystemExit, match=r'2'):
parse_args(['--dynamic-whitelist', 'abc'], '')
def test_parse_args_backtesting_invalid():
with pytest.raises(SystemExit, match=r'2'):
parse_args(['backtesting --ticker-interval'], '')
with pytest.raises(SystemExit, match=r'2'):
parse_args(['backtesting --ticker-interval', 'abc'], '')
def test_scripts_options():
# Test with -p arg given
args = ['-p', 'BTC_ETH']
parser = argparse.ArgumentParser()
misc.scripts_options(parser)
call_args = parser.parse_args(args)
assert call_args.pair == 'BTC_ETH'
# Test with NO -p arg given
parser = argparse.ArgumentParser()
misc.scripts_options(parser)
call_args = parser.parse_args([])
assert not call_args.pair
def test_parse_args_backtesting_custom():
args = [
'-c', 'test_conf.json',
'backtesting',
'--live',
'--ticker-interval', '1',
'--refresh-pairs-cached']
call_args = parse_args(args, '')
assert call_args.config == 'test_conf.json'
assert call_args.live is True
assert call_args.loglevel == 20
assert call_args.subparser == 'backtesting'
assert call_args.func is not None
assert call_args.ticker_interval == 1
assert call_args.refresh_pairs is True
def test_parse_args_hyperopt_custom():
args = ['-c', 'test_conf.json', 'hyperopt', '--epochs', '20']
call_args = parse_args(args, '')
assert call_args.config == 'test_conf.json'
assert call_args.epochs == 20
assert call_args.loglevel == 20
assert call_args.subparser == 'hyperopt'
assert call_args.func is not None
def test_file_dump_json(mocker):
file_open = mocker.patch('freqtrade.misc.open', MagicMock())
json_dump = mocker.patch('json.dump', MagicMock())
file_dump_json('somefile', [1, 2, 3])
assert file_open.call_count == 1
assert json_dump.call_count == 1
def test_parse_timerange_incorrect():
assert ((None, 'line'), None, -200) == parse_timerange('-200')
assert (('line', None), 200, None) == parse_timerange('200-')
with pytest.raises(Exception, match=r'Incorrect syntax.*'):
parse_timerange('-')
def test_load_config(default_conf, mocker):
file_mock = mocker.patch('freqtrade.misc.open', mocker.mock_open(
read_data=json.dumps(default_conf)
))
validated_conf = load_config('somefile')
assert file_mock.call_count == 1
assert validated_conf.items() >= default_conf.items()
def test_load_config_invalid_pair(default_conf, mocker):
conf = deepcopy(default_conf)
conf['exchange']['pair_whitelist'].append('BTC-ETH')
mocker.patch(
'freqtrade.misc.open',
mocker.mock_open(
read_data=json.dumps(conf)))
with pytest.raises(ValidationError, match=r'.*does not match.*'):
load_config('somefile')
def test_load_config_missing_attributes(default_conf, mocker):
conf = deepcopy(default_conf)
conf.pop('exchange')
mocker.patch(
'freqtrade.misc.open',
mocker.mock_open(
read_data=json.dumps(conf)))
with pytest.raises(ValidationError, match=r'.*\'exchange\' is a required property.*'):
load_config('somefile')
def test_datesarray_to_datetimearray(ticker_history):
dataframes = parse_ticker_dataframe(ticker_history)
dates = datesarray_to_datetimearray(dataframes['date'])
assert isinstance(dates[0], datetime.datetime)
assert dates[0].year == 2017
assert dates[0].month == 11
assert dates[0].day == 26
assert dates[0].hour == 8
assert dates[0].minute == 50
date_len = len(dates)
assert date_len == 3
def test_common_datearray():
dts = [datetime.datetime(2018, 2, 1),
datetime.datetime(2018, 2, 2),
datetime.datetime(2018, 2, 3),
datetime.datetime(2018, 2, 4)]
dt64 = [np.datetime64(dt) for dt in dts]
def check(totlen, idx1, idx2):
df1 = pd.DataFrame([[dt64[x], x] for x in idx1],
columns=['date', 'foo'])
df2 = pd.DataFrame([[dt64[x], x] for x in idx2],
columns=['date', 'foo'])
datearray = misc.common_datearray({'q1': df1, 'q2': df2})
assert len(datearray) == totlen
for i in range(0, totlen):
assert dts[i] == datearray[i]
# ensure two merged date arrays with unique dates
check(4, [0, 2], [1, 3])
# ensure two merged date arrays with unique dates
check(4, [0, 2], [1, 2, 3])
# ensure unsorted arrays result in sorted arrays
check(4, [2, 0], [3, 1])