Files @ 93fffe6666ec
Branch filter:

Location: NPO-Accounting/import2ledger/tests/test_importers.py

Brett Smith
importers: New importer for North Bay Python invoices.

This probably has no use outside Conservancy.
import datetime
import decimal
import importlib
import itertools
import pathlib
import re

import pytest
import yaml
from import2ledger import importers

from . import DATA_DIR

class TestImporters:
    def _value_converter(value):
        try:
            is_decimal = re.match(r'^[-+]?\d+\.\d+$', value)
        except TypeError:
            is_decimal = False
        if is_decimal:
            return decimal.Decimal
        else:
            return lambda x: x

    def _date(parts_list):
        return datetime.date(*parts_list)

    KEY_CONVERTERS = {
        'date': _date,
    }

    with pathlib.Path(DATA_DIR, 'imports.yml').open() as yaml_file:
        test_data = yaml.load(yaml_file)
    for test in test_data:
        test['source'] = DATA_DIR / test['source']

        module_name, class_name = test['importer'].rsplit('.', 1)
        module = importlib.import_module('.' + module_name, 'import2ledger.importers')
        test['importer'] = getattr(module, class_name)

        for expect_result in test['expect']:
            for key, value in expect_result.items():
                try:
                    convert_func = KEY_CONVERTERS[key]
                except KeyError:
                    convert_func = _value_converter(value)
                expect_result[key] = convert_func(value)

    @pytest.mark.parametrize('source_path,importer', [
        (t['source'], t['importer']) for t in test_data
    ])
    def test_can_import(self, source_path, importer):
        with source_path.open() as source_file:
            assert importer.can_import(source_file)

    @pytest.mark.parametrize('source_path,import_class,expect_results', [
        (t['source'], t['importer'], t['expect']) for t in test_data
    ])
    def test_import(self, source_path, import_class, expect_results):
        with source_path.open() as source_file:
            importer = import_class(source_file)
            for actual, expected in itertools.zip_longest(importer, expect_results):
                actual['amount'] = decimal.Decimal(actual['amount'])
                assert actual == expected

    def test_loader(self):
        all_importers = list(importers.load_all())
        for test in self.test_data:
            assert test['importer'] in all_importers