2019-08-28 14:22:10 +00:00
|
|
|
import csv
|
2017-10-22 17:38:53 +00:00
|
|
|
import datetime
|
2017-11-09 20:06:02 +00:00
|
|
|
import decimal
|
2019-08-28 14:22:10 +00:00
|
|
|
import io
|
2017-10-22 17:38:53 +00:00
|
|
|
import importlib
|
|
|
|
import itertools
|
|
|
|
import pathlib
|
2019-08-28 14:22:10 +00:00
|
|
|
import shutil
|
2017-12-17 18:42:51 +00:00
|
|
|
import re
|
2017-10-22 17:38:53 +00:00
|
|
|
|
|
|
|
import pytest
|
|
|
|
import yaml
|
2017-12-19 11:42:05 +00:00
|
|
|
from import2ledger import importers, strparse
|
2017-10-22 17:38:53 +00:00
|
|
|
|
|
|
|
from . import DATA_DIR
|
|
|
|
|
2019-10-08 14:47:27 +00:00
|
|
|
try:
|
|
|
|
load_yaml = yaml.full_load
|
|
|
|
except AttributeError:
|
|
|
|
load_yaml = yaml.load
|
|
|
|
|
2017-10-22 17:38:53 +00:00
|
|
|
class TestImporters:
|
|
|
|
with pathlib.Path(DATA_DIR, 'imports.yml').open() as yaml_file:
|
2019-10-08 14:47:27 +00:00
|
|
|
test_data = load_yaml(yaml_file)
|
2017-10-22 17:38:53 +00:00
|
|
|
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)
|
|
|
|
|
2019-08-28 14:22:10 +00:00
|
|
|
@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)
|
|
|
|
|
2017-10-22 17:38:53 +00:00
|
|
|
@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):
|
2017-12-19 11:42:05 +00:00
|
|
|
actual['amount'] = strparse.currency_decimal(actual['amount'])
|
2017-10-22 17:38:53 +00:00
|
|
|
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
|