Files @ fcd14f3c4466
Branch filter:

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

Brett Smith
github: Update to match fiscal host reporting.

In general the fiscal host reporting isn't as nice as the project reporting,
so I hope someday we can revert this change, but until then that's what
we're using.
import csv
import datetime
import decimal
import io
import importlib
import itertools
import pathlib
import shutil
import re

import pytest
import yaml
from import2ledger import importers, strparse

from . import DATA_DIR

try:
    load_yaml = yaml.full_load
except AttributeError:
    load_yaml = yaml.load

class TestImporters:
    with pathlib.Path(DATA_DIR, 'imports.yml').open() as yaml_file:
        test_data = load_yaml(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('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,importer,header_rows,header_cols', [
        (t['source'], t['importer'], t['header_rows'], t['header_cols'])
        for t in test_data if t.get('header_rows')
    ])
    def test_can_import_squared_csv(self, source_path, importer, header_rows, header_cols):
        # Sometimes when we munge spreadsheets by hand (e.g., to filter by
        # project) tools like LibreOffice Calc write a "squared" spreadsheet,
        # where every row has the same length.  This test ensures the results
        # are still recognized for import.
        with io.StringIO() as squared_file:
            csv_writer = csv.writer(squared_file)
            with source_path.open() as source_file:
                for row in itertools.islice(csv.reader(source_file), header_rows):
                    padding = [None] * (header_cols - len(row))
                    csv_writer.writerow(row + padding)
                shutil.copyfileobj(source_file, squared_file)
            squared_file.seek(0)
            assert importer.can_import(squared_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'] = strparse.currency_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