Files @ ea0e3d3a73b7
Branch filter:

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

Brett Smith
dynload: Pre-configure objects and skip unconfigured ones.

Now that all importers and hooks receive the configuration object, they can
tell us at initialization time whether or not they actually have enough
configuration to be useful. Initialize them immediately on loading, and
only use importers and hooks that are actually configured.
import datetime
import decimal
import importlib
import itertools
import pathlib
import re

import pytest
import yaml
from import2ledger import errors, importers, strparse

from . import Config, DATA_DIR

class TestImporters:
    FULL_CONFIG = Config({})

    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)

    @pytest.mark.parametrize('importer,needs_config', [
        (t['importer'], t.get('needs_config')) for t in test_data
    ])
    def test_configuration(self, importer, needs_config):
        importer(Config())

    @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(Config()).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(Config())
            actual_results = importer.iter_entries(source_file)
            for actual, expected in itertools.zip_longest(actual_results, expect_results):
                actual['amount'] = strparse.currency_decimal(actual['amount'])
                assert actual == expected

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