Changeset - 751cd7cd441e
[Not reviewed]
0 8 2
Brett Smith - 6 years ago 2018-04-03 15:25:31
brettcsmith@brettcsmith.org
config/hooks: Date hooks configure themselves.

Broadly, this change gets date-specific configuration out of the Config
class, and into the date hooks. Following this pattern, we can have more
specific configuration for more hooks without growing a bunch of custom
methods on the Config class.

There's still more cleanup to be done to finish the job, but this commit is
about as big as I can stand, so this will serve as a good checkpoint.
10 files changed with 252 insertions and 188 deletions:
0 comments (0 inline, 0 general)
import2ledger/config.py
Show inline comments
...
 
@@ -17,16 +17,6 @@ class Configuration:
 
    DEFAULT_ENCODING = locale.getpreferredencoding()
 
    LOCALE = babel.core.Locale.default()
 
    TODAY = datetime.date.today()
 
    CONFIG_DEFAULTS = {
 
        'date_format': '%%Y/%%m/%%d',
 
        'date_range': '-',
 
        'loglevel': 'WARNING',
 
        'output_path': '-',
 
        'signed_currencies': ','.join(babel.numbers.get_territory_currencies(
 
            LOCALE.territory, start_date=TODAY)),
 
        'signed_currency_format': '¤#,##0.###;¤-#,##0.###',
 
        'unsigned_currency_format': '#,##0.### ¤¤',
 
    }
 

	
 
    def __init__(self, arglist, stdout, stderr):
 
        self.stdout = stdout
...
 
@@ -71,26 +61,28 @@ class Configuration:
 
            description="These options take priority over settings in the "
 
            "[DEFAULT] section of your config file, but not other sections.",
 
        )
 
        out_args.add_argument(
 
            '--date', '-d', metavar='DATE',
 
            help="Date to use in Ledger entries when the source doesn't "
 
            "provide one. Write this in your configured date format. "
 
            "Default today.",
 
        )
 
        out_args.add_argument(
 
            '--date-format', '-D', metavar='FORMAT',
 
            help="Date format to use in Ledger entries",
 
            help="C-style date format to use to parse dates given in other "
 
            "options. This format will also be used for configuration parsing "
 
            "and output generation when no date format is specified in your "
 
            "configuration file(s). If not specified, read from the [Dates] "
 
            "section of your configuration, or else `%Y/%m/%d`.",
 
        )
 
        out_args.add_argument(
 
            '--date-range', metavar='DATE-DATE',
 
            help="Only import entries in this date range, inclusive. "
 
            "Write dates in your configured date format. "
 
            "You can omit either side of the range.",
 
        )
 
        out_args.add_argument(
 
            '--default-date', '--date', '-d', metavar='DATE',
 
            help="Date to assign entries when the source doesn't "
 
            "provide one. Default today.",
 
        )
 
        out_args.add_argument(
 
            '--loglevel', '-L', metavar='LEVEL',
 
            choices=['debug', 'info', 'warning', 'error', 'critical'],
 
            help="Log messages at this level and above. Default WARNING.",
 
            help="Log messages at this level and above. Default warning.",
 
        )
 
        out_args.add_argument(
 
            '--output-path', '-O', metavar='PATH',
...
 
@@ -116,8 +108,14 @@ class Configuration:
 
    def _build_conffile(self):
 
        return configparser.ConfigParser(
 
            comment_prefixes='#',
 
            defaults=self.CONFIG_DEFAULTS,
 
        )
 
            defaults={
 
                'loglevel': 'WARNING',
 
                'output_path': '-',
 
                'signed_currencies': ','.join(babel.numbers.get_territory_currencies(
 
                    self.LOCALE.territory, start_date=self.TODAY)),
 
                'signed_currency_format': '¤#,##0.###;¤-#,##0.###',
 
                'unsigned_currency_format': '#,##0.### ¤¤',
 
            })
 

	
 
    def _s_to_path(self, s):
 
        return None if s == '-' else pathlib.Path(s)
...
 
@@ -128,66 +126,62 @@ class Configuration:
 
        except ValueError as error:
 
            raise errors.UserInputConfigurationError(error.args[0], date_s)
 

	
 
    def _parse_section_date(self, section_name, default=TODAY):
 
        section = self.conffile[section_name]
 
        try:
 
            return self._strpdate(section['date'], section['date_format'])
 
        except KeyError:
 
            return default
 

	
 
    def _parse_date_range(self, section_name):
 
        section = self.conffile[section_name]
 
        range_s = section['date_range']
 
        date_fmt = section['date_format']
 
        if not range_s:
 
            range_s = '-'
 
        if range_s.startswith('-'):
 
            start_s = ''
 
            end_s = range_s[1:]
 
        elif range_s.endswith('-'):
 
            start_s = range_s[:-1]
 
            end_s = ''
 
        else:
 
            range_parts = range_s.split('-')
 
            mid_index = len(range_parts) // 2
 
            start_s = '-'.join(range_parts[:mid_index])
 
            end_s = '-'.join(range_parts[mid_index:])
 
        start_d = self._strpdate(start_s, date_fmt) if start_s else datetime.date.min
 
        end_d = self._strpdate(end_s, date_fmt) if end_s else datetime.date.max
 
        return range(start_d.toordinal(), end_d.toordinal() + 1)
 
    def _reformat_date(self, date_s, in_fmt, out_fmt):
 
        return self._strpdate(date_s, in_fmt).strftime(out_fmt)
 

	
 
    def finalize(self):
 
        default_secname = self.conffile.default_section
 
        default_section = self.get_section(default_secname)
 
        if self.args.use_config is None:
 
            self.args.use_config = default_secname
 
        elif not self.conffile.has_section(self.args.use_config):
 
            self.error("section {!r} not found in config file".format(self.args.use_config))
 
        self.args.input_paths = [self._s_to_path(s) for s in self.args.input_paths]
 

	
 
        defaults = self.conffile[default_secname]
 
        for key in self.CONFIG_DEFAULTS:
 
            value = getattr(self.args, key)
 
            if value is None:
 
                pass
 
            elif key == 'signed_currencies':
 
                defaults[key] = ','.join(value)
 
            else:
 
                defaults[key] = value.replace('%', '%%')
 
        if self.args.loglevel is not None:
 
            default_section['loglevel'] = self.args.loglevel
 
        if self.args.output_path is not None:
 
            default_section['output_path'] = self.args.output_path
 

	
 
        # We parse all the dates now to make sure they're valid.
 
        if self.args.date is not None:
 
            default_date = self._strpdate(self.args.date, defaults['date_format'])
 
        elif 'date' in defaults:
 
            default_date = self._strpdate(defaults['date'], defaults['date_format'])
 
        else:
 
            default_date = self.TODAY
 

	
 
        self.dates = {secname: self._parse_section_date(secname, default_date)
 
                      for secname in self.conffile}
 
        self.dates[default_secname] = default_date
 
        self.date_ranges = {secname: self._parse_date_range(secname)
 
                            for secname in self.conffile}
 
        self.date_ranges[default_secname] = self._parse_date_range(default_secname)
 
        dates_section = self.get_section('Dates')
 
        try:
 
            out_fmt = dates_section['date format']
 
        except KeyError:
 
            if self.args.date_format is None:
 
                out_fmt = '%Y/%m/%d'
 
            else:
 
                out_fmt = self.args.date_format
 
            default_section['date format'] = out_fmt.replace('%', '%%')
 
        in_fmt = self.args.date_format or out_fmt
 
        if self.args.default_date is not None:
 
            dates_section['default date'] = self._reformat_date(
 
                self.args.default_date, in_fmt, out_fmt)
 
        if self.args.date_range is not None:
 
            if self.args.date_range.startswith('-'):
 
                pivot = 0
 
            elif self.args.date_range.endswith('-'):
 
                pivot = len(self.args.date_range) - 1
 
            else:
 
                seps_at = [index for index, c in enumerate(self.args.date_range) if c == '-']
 
                seps_count = len(seps_at)
 
                if seps_count % 2:
 
                    pivot = seps_at[(seps_count - 1) // 2]
 
                else:
 
                    start_s = end_s = self.args.date_range
 
                    pivot = None
 
            if pivot is not None:
 
                start_s = self.args.date_range[:pivot]
 
                end_s = self.args.date_range[pivot + 1:]
 
            if start_s:
 
                dates_section['import start date'] = self._reformat_date(
 
                    start_s, in_fmt, out_fmt)
 
            else:
 
                dates_section.pop('import start date', None)
 
            if end_s:
 
                dates_section['import end date'] = self._reformat_date(
 
                    end_s, in_fmt, out_fmt)
 
            else:
 
                dates_section.pop('import end date', None)
 

	
 
    @contextlib.contextmanager
 
    def _open_path(self, path, fallback_file, *args, **kwargs):
import2ledger/hooks/default_date.py
Show inline comments
 
import configparser
 

	
 
from . import HOOK_KINDS
 
from .. import errors, strparse
 

	
 
class DefaultDateHook:
 
    KIND = HOOK_KINDS.DATA_ADDER
 

	
 
    def __init__(self, config):
 
        self.config = config
 
        date_config = config.get_section('Dates')
 
        try:
 
            default_date_s = date_config['default date']
 
        except KeyError:
 
            raise errors.NotConfiguredError("`default date` not set", None)
 
        try:
 
            default_date = strparse.date(default_date_s, date_config['date format'])
 
        except ValueError as error:
 
            raise errors.UserInputConfigurationError(error.args[0], default_date_s)
 
        self.default_date = default_date
 

	
 
    def run(self, entry_data):
 
        if 'date' not in entry_data:
 
            entry_data['date'] = self.config.get_default_date()
 
            entry_data['date'] = self.default_date
import2ledger/hooks/filter_by_date.py
Show inline comments
 
import datetime
 

	
 
from . import HOOK_KINDS
 

	
 
from .. import errors, strparse
 

	
 
class FilterByDateHook:
 
    KIND = HOOK_KINDS.DATA_FILTER
 

	
 
    def __init__(self, config):
 
        self.config = config
 
        date_config = config.get_section('Dates')
 
        start_date = self._get_date(date_config, 'import start date', datetime.date.min)
 
        end_date = self._get_date(date_config, 'import end date', datetime.date.max)
 
        if start_date is datetime.date.min and end_date is datetime.date.max:
 
            raise errors.NotConfiguredError("no import start or end date set", None)
 
        self.date_range = range(start_date.toordinal(), end_date.toordinal() + 1)
 

	
 
    def _get_date(self, date_config, key, default):
 
        try:
 
            date_s = date_config[key]
 
        except KeyError:
 
            return default
 
        else:
 
            try:
 
                return strparse.date(date_s, date_config['date format'])
 
            except ValueError as error:
 
                raise errors.UserInputConfigurationError(error.args[0], date_s)
 

	
 
    def run(self, entry_data):
 
        try:
...
 
@@ -12,5 +32,5 @@ class FilterByDateHook:
 
        except KeyError:
 
            pass
 
        else:
 
            if not self.config.date_in_want_range(date):
 
            if date.toordinal() not in self.date_range:
 
                return False
import2ledger/hooks/ledger_entry.py
Show inline comments
...
 
@@ -291,7 +291,7 @@ class LedgerEntryHook:
 
            )
 
        return Template(
 
            template_s,
 
            date_fmt=section_config['date_format'],
 
            date_fmt=section_config['date format'],
 
            signed_currencies=[code.strip().upper() for code in section_config['signed_currencies'].split(',')],
 
            signed_currency_fmt=section_config['signed_currency_format'],
 
            unsigned_currency_fmt=section_config['unsigned_currency_format'],
tests/data/templates.ini
Show inline comments
 
[DEFAULT]
 
date_format = %%Y-%%m-%%d
 
date format = %%Y-%%m-%%d
 
signed_currencies = USD, CAD
 
signed_currency_format = ¤#,##0.###
 
unsigned_currency_format = #,##0.### ¤¤
tests/data/test_config.ini
Show inline comments
 
[DEFAULT]
 
date_format = %%Y-%%m-%%d
 
date format = %%Y-%%m-%%d
 
signed_currencies = EUR
 

	
 
[Templates]
...
 
@@ -16,9 +16,9 @@ two =
 
 Accrued:Accounts Receivable  .95 * {amount}
 
 ;AccrualTag: Receivable
 

	
 
[Date]
 
date_format = %%Y|%%m|%%d
 
date = 2017|10|08
 
[Dates]
 
date format = %%Y|%%m|%%d
 
default date = 2017|10|08
 

	
 
[Bad Loglevel]
 
loglevel = wraning
tests/test_config.py
Show inline comments
...
 
@@ -10,7 +10,7 @@ START_DATE = datetime.date.today()
 
from unittest import mock
 

	
 
import pytest
 
from import2ledger import config, errors
 
from import2ledger import config, errors, strparse
 

	
 
from . import DATA_DIR
 

	
...
 
@@ -22,18 +22,15 @@ def config_from_file(path, arglist=[], stdout=None, stderr=None):
 
    return config.Configuration(arglist, stdout, stderr)
 

	
 
def test_get_section():
 
    config = config_from_file('test_config.ini', ['--date-format', '%m/%d/%Y'])
 
    config = config_from_file('test_config.ini')
 
    section = config.get_section('Templates')
 
    assert section['output_path'] == 'Template.output'
 
    assert section['date_format'] == '%m/%d/%Y'
 
    assert section['signed_currencies'] == 'EUR'
 

	
 
def test_get_section_falls_back_to_default():
 
    config = config_from_file('test_config.ini', ['--date-format', '%m/%d/%Y'])
 
    config = config_from_file('test_config.ini')
 
    section = config.get_section('Nonexistent Templates Section')
 
    assert 'one' not in section
 
    assert 'default date' not in section
 
    assert section['date_format'] == '%m/%d/%Y'
 
    assert section.get('output_path') != 'Template.output'
 
    assert section['signed_currencies'] == 'EUR'
 

	
 
@pytest.mark.parametrize('arg_s', [None, '-', 'output.ledger'])
...
 
@@ -46,35 +43,51 @@ def test_output_path(arg_s):
 
    else:
 
        assert output_path == pathlib.Path(arg_s)
 

	
 
@pytest.mark.parametrize('range_s,date_fmt', [
 
    (range_s.replace('/', sep), sep.join(['%Y', '%m', '%d']))
 
    for range_s, sep in itertools.product([
 
            '-',
 
            '2016/06/01-2016/06/30',
 
            '2016/06/01-',
 
            '-2016/06/30',
 
            ], '/-')
 
])
 
def test_date_in_want_range(range_s, date_fmt):
 
    config = config_from_file(os.devnull, ['--date-range=' + range_s, '--date-format', date_fmt])
 
    assert config.date_in_want_range(datetime.date(2016, 5, 31)) == range_s.startswith('-')
 
    assert config.date_in_want_range(datetime.date(2016, 6, 1))
 
    assert config.date_in_want_range(datetime.date(2016, 6, 30))
 
    assert config.date_in_want_range(datetime.date(2016, 7, 1)) == range_s.endswith('-')
 
def _fix_date_s(date_s, new_sep, old_sep='/'):
 
    return date_s.replace(old_sep, new_sep)
 

	
 
@pytest.mark.parametrize('range_s,sep', itertools.product([
 
    '-',
 
    '2016/06/01-2016/06/30',
 
    '2016/06/01-',
 
    '-2016/06/30',
 
], '/-'))
 
def test_date_range(range_s, sep):
 
    raw_start, _, raw_end = range_s.partition('-')
 
    expect_start = _fix_date_s(raw_start, sep)
 
    expect_end = _fix_date_s(raw_end, sep)
 
    config = config_from_file(os.devnull, [
 
        '--date-range=' + _fix_date_s(range_s, sep),
 
        '--date-format', _fix_date_s('%Y/%m/%d', sep),
 
    ])
 
    section = config.get_section('Dates')
 
    actual_start = section.get('import start date')
 
    assert actual_start == (expect_start or None)
 
    actual_end = section.get('import end date')
 
    assert actual_end == (expect_end or None)
 

	
 
@pytest.mark.parametrize('arglist,expect_date', [
 
    ([], None),
 
    (['-d', '2017-10-12'], datetime.date(2017, 10, 12)),
 
    (['-c', 'Date'], datetime.date(2017, 10, 8)),
 
@pytest.mark.parametrize('config_filename,date_fmt,date_arg,expect_date', [
 
    (os.devnull, '%Y-%m-%d', '2017-01-05', None),
 
    (os.devnull, '%Y/%m/%d', '2017/01/06', None),
 
    ('test_config.ini', '%Y-%m-%d', None, '2017|10|08'),
 
    ('test_config.ini', '%Y-%m-%d', '2017-01-12', '2017|01|12'),
 
])
 
def test_default_date(arglist, expect_date):
 
    config = config_from_file('test_config.ini', arglist)
 
    default_date = config.get_default_date()
 
    if expect_date is None:
 
        assert START_DATE <= default_date <= datetime.date.today()
 
def test_default_date(config_filename, date_fmt, date_arg, expect_date):
 
    arglist = ['--date-format', date_fmt]
 
    if date_arg is not None:
 
        arglist += ['--default-date', date_arg]
 
    config = config_from_file(config_filename, arglist)
 
    date_section = config.get_section('Dates')
 
    actual_date = date_section['default date']
 
    if expect_date is not None:
 
        assert actual_date == expect_date
 
    else:
 
        assert default_date == expect_date
 
    assert config.get_default_date('Date') == datetime.date(2017, 10, 8)
 
        default_date = strparse.date(actual_date, date_section['date format'])
 
        if date_arg is not None:
 
            target_date = strparse.date(date_arg, date_fmt)
 
            assert default_date == target_date
 
        else:
 
            assert START_DATE <= default_date <= datetime.date.today()
 

	
 
@pytest.mark.parametrize('level_s,expect_level', [
 
    (s, getattr(logging, s.upper()))
tests/test_hooks.py
Show inline comments
 
import argparse
 
import datetime
 
import itertools
 

	
 
import pytest
 

	
 
from import2ledger import hooks
 
from import2ledger.hooks import add_entity, default_date, filter_by_date, ledger_entry
 

	
...
 
@@ -29,71 +23,3 @@ def test_load_all():
 
        filter_by_date.FilterByDateHook,
 
        ledger_entry.LedgerEntryHook,
 
    ])
 

	
 
class DateRangeConfig:
 
    def __init__(self, start_date=None, end_date=None):
 
        self.start_date = start_date
 
        self.end_date = end_date
 

	
 
    def date_in_want_range(self, date):
 
        return (
 
            ((self.start_date is None) or (date >= self.start_date))
 
            and ((self.end_date is None) or (date <= self.end_date))
 
        )
 

	
 

	
 
@pytest.mark.parametrize('entry_date,start_date,end_date,allowed', [
 
    (datetime.date(2016, 5, 10), datetime.date(2016, 1, 1), datetime.date(2016, 12, 31), True),
 
    (datetime.date(2016, 1, 1), datetime.date(2016, 1, 1), datetime.date(2016, 12, 31), True),
 
    (datetime.date(2016, 12, 31), datetime.date(2016, 1, 1), datetime.date(2016, 12, 31), True),
 
    (datetime.date(2016, 1, 1), datetime.date(2016, 1, 1), None, True),
 
    (datetime.date(2016, 12, 31), None, datetime.date(2016, 12, 31), True),
 
    (datetime.date(1999, 1, 2), None, None, True),
 
    (datetime.date(2016, 1, 25), datetime.date(2016, 2, 1), datetime.date(2016, 12, 31), False),
 
    (datetime.date(2016, 12, 26), datetime.date(2016, 1, 1), datetime.date(2016, 11, 30), False),
 
    (datetime.date(2016, 1, 31), datetime.date(2016, 2, 1), None, False),
 
    (datetime.date(2016, 12, 1), None, datetime.date(2016, 11, 30), False),
 
])
 
def test_filter_by_date(entry_date, start_date, end_date, allowed):
 
    entry_data = {'date': entry_date}
 
    hook = filter_by_date.FilterByDateHook(DateRangeConfig(start_date, end_date))
 
    assert hook.run(entry_data) is (None if allowed else False)
 

	
 
class DefaultDateConfig:
 
    ONE_DAY = datetime.timedelta(days=1)
 

	
 
    def __init__(self, start_date=None):
 
        if start_date is None:
 
            start_date = datetime.date(2016, 3, 5)
 
        self.date = start_date - self.ONE_DAY
 

	
 
    def get_default_date(self, section_name=None):
 
        self.date += self.ONE_DAY
 
        return self.date
 

	
 

	
 
class TestDefaultDate:
 
    def test_simple_case(self):
 
        expect_date = datetime.date(2016, 2, 4)
 
        config = DefaultDateConfig(expect_date)
 
        data = {}
 
        hook = default_date.DefaultDateHook(config)
 
        hook.run(data)
 
        assert data['date'] == expect_date
 

	
 
    def test_no_caching(self):
 
        config = DefaultDateConfig()
 
        hook = default_date.DefaultDateHook(config)
 
        d1 = {}
 
        d2 = {}
 
        hook.run(d1)
 
        hook.run(d2)
 
        assert d1['date'] != d2['date']
 

	
 
    def test_no_override(self):
 
        expect_date = datetime.date(2016, 2, 6)
 
        config = DefaultDateConfig(expect_date + datetime.timedelta(days=300))
 
        hook = default_date.DefaultDateHook(config)
 
        data = {'date': expect_date}
 
        hook.run(data)
 
        assert data['date'] is expect_date
tests/test_hooks_default_date.py
Show inline comments
 
new file 100644
 
import datetime
 

	
 
import pytest
 
from import2ledger import errors
 
from import2ledger.hooks import default_date as default_date_mod
 

	
 
from . import Config
 
from . date_hooks import DateHookTestBase
 

	
 
class TestDefaultDateHook(DateHookTestBase):
 
    format_params = pytest.mark.parametrize('fmt,default_date', [
 
        (DateHookTestBase.DATE_FMT_ISO, datetime.date(2017, 3, 5)),
 
        (DateHookTestBase.DATE_FMT_LEDGER, datetime.date(2017, 3, 10)),
 
    ])
 

	
 
    def build_hook(self, fmt, default_date):
 
        config_dict = self.new_config(fmt, default_date=default_date)
 
        return default_date_mod.DefaultDateHook(Config(config_dict))
 

	
 
    @format_params
 
    def test_default_date_added(self, fmt, default_date):
 
        hook = self.build_hook(fmt, default_date)
 
        entry_data = {}
 
        hook.run(entry_data)
 
        assert entry_data['date'] == default_date
 

	
 
    @format_params
 
    def test_date_not_overridden(self, fmt, default_date):
 
        hook = self.build_hook(fmt, default_date)
 
        date_s = datetime.date(2016, 12, 12).strftime(fmt)
 
        entry_data = {'date': date_s}
 
        hook.run(entry_data)
 
        assert entry_data['date'] == date_s
 

	
 
    def test_not_configured(self):
 
        with pytest.raises(errors.NotConfiguredError):
 
            default_date_mod.DefaultDateHook(Config())
 

	
 
    def test_bad_config(self):
 
        config_dict = {'Dates': {
 
            'date format': '%%Y-%%m-%%d',
 
            'default date': '15 Aug 2017',
 
        }}
 
        with pytest.raises(errors.UserInputConfigurationError):
 
            default_date_mod.DefaultDateHook(Config(config_dict))
tests/test_hooks_filter_by_date.py
Show inline comments
 
new file 100644
 
import datetime
 

	
 
import pytest
 
from import2ledger import errors
 
from import2ledger.hooks import filter_by_date
 

	
 
from . import Config
 
from . date_hooks import DateHookTestBase
 

	
 
class TestFilterByDateHook(DateHookTestBase):
 
    @pytest.mark.parametrize('fmt', [
 
        DateHookTestBase.DATE_FMT_ISO,
 
        DateHookTestBase.DATE_FMT_LEDGER,
 
    ])
 
    @pytest.mark.parametrize('test_date,allowed', [
 
        (datetime.date(2017, 2, 1), True),
 
        (datetime.date(2017, 2, 20), True),
 
        (datetime.date(2017, 3, 10), True),
 
        (datetime.date(2017, 4, 1), True),
 
        (datetime.date(2017, 1, 31), False),
 
        (datetime.date(2017, 4, 2), False),
 
    ])
 
    def test_filtering(self, fmt, test_date, allowed):
 
        config_dict = self.new_config(fmt)
 
        hook = filter_by_date.FilterByDateHook(Config(config_dict))
 
        assert hook.run({'date': test_date}) is (None if allowed else False)
 

	
 
    def test_start_date_only(self):
 
        config_dict = self.new_config(end_date=None)
 
        hook = filter_by_date.FilterByDateHook(Config(config_dict))
 
        assert hook.run({'date': datetime.date.min}) is False
 
        assert hook.run({'date': datetime.date(2017, 1, 31)}) is False
 
        assert hook.run({'date': datetime.date(2017, 2, 1)}) is None
 
        assert hook.run({'date': datetime.date.max}) is None
 

	
 
    def test_end_date_only(self):
 
        config_dict = self.new_config(start_date=None)
 
        hook = filter_by_date.FilterByDateHook(Config(config_dict))
 
        assert hook.run({'date': datetime.date.min}) is None
 
        assert hook.run({'date': datetime.date(2017, 4, 1)}) is None
 
        assert hook.run({'date': datetime.date(2017, 4, 2)}) is False
 
        assert hook.run({'date': datetime.date.max}) is False
 

	
 
    def test_not_configured(self):
 
        with pytest.raises(errors.NotConfiguredError):
 
            filter_by_date.FilterByDateHook(Config())
 

	
 
    def test_bad_config(self):
 
        config_dict = {'Dates': {
 
            'date format': '%%Y-%%m-%%d',
 
            'import start date': '15 Aug 2017',
 
        }}
 
        with pytest.raises(errors.UserInputConfigurationError):
 
            filter_by_date.FilterByDateHook(Config(config_dict))
0 comments (0 inline, 0 general)