stable/freqtrade/tests/test_misc.py

181 lines
4.9 KiB
Python
Raw Normal View History

# pragma pylint: disable=missing-docstring,C0103
2018-01-10 07:51:36 +00:00
import argparse
import json
import time
from copy import deepcopy
2017-11-11 15:47:19 +00:00
2017-11-17 16:19:00 +00:00
import pytest
2018-01-11 14:49:04 +00:00
from unittest.mock import MagicMock
from jsonschema import ValidationError
2017-11-17 16:19:00 +00:00
2018-01-10 07:51:36 +00:00
from freqtrade.misc import (common_args_parser, load_config, parse_args,
throttle, file_dump_json, parse_timerange)
2017-11-11 15:47:19 +00:00
def test_throttle():
def func():
return 42
start = time.time()
2017-12-30 14:55:49 +00:00
result = throttle(func, min_secs=0.1)
2017-11-11 15:47:19 +00:00
end = time.time()
assert result == 42
assert end - start > 0.1
2017-12-30 14:55:49 +00:00
result = throttle(func, min_secs=-1)
2017-11-11 15:47:19 +00:00
assert result == 42
2017-11-17 16:19:00 +00:00
2017-12-30 14:55:49 +00:00
def test_throttle_with_assets():
2017-12-30 14:55:49 +00:00
def func(nb_assets=-1):
return nb_assets
2017-12-30 14:55:49 +00:00
result = throttle(func, min_secs=0.1, nb_assets=666)
assert result == 666
2017-12-30 14:55:49 +00:00
result = throttle(func, min_secs=0.1)
assert result == -1
2018-01-09 11:06:28 +00:00
# Parse common command-line-arguments. Used for all tools
def test_parse_args_none():
2018-01-09 11:06:28 +00:00
args = common_args_parser('')
assert isinstance(args, argparse.ArgumentParser)
2017-11-17 16:19:00 +00:00
def test_parse_args_defaults():
args = parse_args([], '')
2017-11-17 16:19:00 +00:00
assert args.config == 'config.json'
assert args.dynamic_whitelist is None
2017-11-17 16:19:00 +00:00
assert args.loglevel == 20
def test_parse_args_config():
args = parse_args(['-c', '/dev/null'], '')
2017-11-17 16:19:00 +00:00
assert args.config == '/dev/null'
args = parse_args(['--config', '/dev/null'], '')
2017-11-17 16:19:00 +00:00
assert args.config == '/dev/null'
def test_parse_args_verbose():
args = parse_args(['-v'], '')
2017-11-17 16:19:00 +00:00
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
2017-11-17 16:19:00 +00:00
def test_parse_args_dynamic_whitelist():
args = parse_args(['--dynamic-whitelist'], '')
2018-01-10 09:17:04 +00:00
assert args.dynamic_whitelist == 20
2017-12-16 02:39:47 +00:00
def test_parse_args_dynamic_whitelist_10():
args = parse_args(['--dynamic-whitelist', '10'], '')
2018-01-10 09:17:04 +00:00
assert args.dynamic_whitelist == 10
2017-12-16 02:39:47 +00:00
def test_parse_args_dynamic_whitelist_invalid_values():
with pytest.raises(SystemExit, match=r'2'):
parse_args(['--dynamic-whitelist', 'abc'], '')
2017-11-17 16:19:00 +00:00
def test_parse_args_backtesting_invalid():
with pytest.raises(SystemExit, match=r'2'):
parse_args(['backtesting --ticker-interval'], '')
2017-11-17 16:19:00 +00:00
with pytest.raises(SystemExit, match=r'2'):
parse_args(['backtesting --ticker-interval', 'abc'], '')
2017-11-17 16:19:00 +00:00
def test_parse_args_backtesting_custom():
args = [
'-c', 'test_conf.json',
'backtesting',
'--live',
'--ticker-interval', '1',
'--refresh-pairs-cached']
call_args = parse_args(args, '')
2017-11-17 16:19:00 +00:00
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
2017-11-17 16:19:00 +00:00
2017-11-25 00:12:44 +00:00
def test_parse_args_hyperopt_custom(mocker):
args = ['-c', 'test_conf.json', 'hyperopt', '--epochs', '20']
call_args = parse_args(args, '')
2017-11-25 00:12:44 +00:00
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
2018-01-11 14:49:04 +00:00
def test_file_dump_json(default_conf, 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
2018-01-15 21:25:02 +00:00
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')
2017-12-30 14:55:49 +00:00
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')
2017-12-30 14:55:49 +00:00
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')