Browse Source

linting with ruff

main
Holger Frey 2 months ago
parent
commit
48527fee63
  1. 4
      Makefile
  2. 16
      pyproject.toml
  3. 12
      superx_budget/__init__.py
  4. 21
      superx_budget/budget.py
  5. 2
      superx_budget/exceptions.py
  6. 32
      superx_budget/helpers.py
  7. 6
      superx_budget/overview.py
  8. 24
      superx_budget/pyramid/__init__.py
  9. 28
      superx_budget/pyramid/overview.py
  10. 13
      superx_budget/pyramid/security.py
  11. 16
      superx_budget/pyramid/templates.py
  12. 22
      superx_budget/superx.py
  13. 10
      tests/conftest.py
  14. 20
      tests/test_helpers.py
  15. 12
      tests/test_overview.py
  16. 12
      tests/test_superx_parser.py

4
Makefile

@ -51,8 +51,8 @@ clean-test: ## remove test and coverage artifacts @@ -51,8 +51,8 @@ clean-test: ## remove test and coverage artifacts
rm -fr htmlcov/
lint: ## reformat with black and check style with flake8
.venv/bin/ruff format src tests noxfile.py
.venv/bin/ruff check src tests noxfile.py
.venv/bin/ruff format superx_budget tests
.venv/bin/ruff check superx_budget tests
test: lint ## run tests quickly with the default Python
.venv/bin/pytest tests -x --disable-warnings -m "not fun"

16
pyproject.toml

@ -9,7 +9,7 @@ name = "superx_budget" @@ -9,7 +9,7 @@ name = "superx_budget"
readme = "README.md"
description = "Creating a budget overview from a SuperX export."
license = { file = "LICENSE" }
requires-python = ">=3.7"
requires-python = ">=3.10"
dynamic = ["version"]
authors = [
@ -20,8 +20,8 @@ authors = [ @@ -20,8 +20,8 @@ authors = [
classifiers = [
"Development Status :: 2 - Pre-Alpha",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3 :: Only",
"License :: Freely Distributable",
]
@ -96,6 +96,16 @@ ignore = [ @@ -96,6 +96,16 @@ ignore = [
# ignored, due to Windows / WSL2 setup
# flake8-executable
"EXE",
# ignored, not really working with datetimes
# just retrieving the year
"DTZ",
# TODO
# checkis for moving project to rust
"ANN",
"TID252",
"PYI024",
]
[tool.ruff.lint.pydocstyle]

12
superx_budget/__init__.py

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
""" superx_budget
"""superx_budget
Creating a budget overview from a SuperX export
"""
@ -6,14 +6,14 @@ Creating a budget overview from a SuperX export @@ -6,14 +6,14 @@ Creating a budget overview from a SuperX export
__version__ = "0.0.1"
from .budget import parse_budget_file # noqa: F401
from .superx import parse_exported_file # noqa: F401
from .exceptions import BudgetParserError, SuperXParserError # noqa: F401
from .helpers import ( # noqa: F401
find_recipients,
find_budget_file,
find_recipients,
get_sheet_of_file,
list_budget_files,
is_budget_file_name,
list_budget_files,
)
from .pyramid import main # noqa: F401
from .overview import create_overview # noqa: F401
from .exceptions import BudgetParserError, SuperXParserError # noqa: F401
from .pyramid import main # noqa: F401
from .superx import parse_exported_file # noqa: F401

21
superx_budget/budget.py

@ -1,9 +1,13 @@ @@ -1,9 +1,13 @@
""" Budget Parser """
"""Budget Parser"""
import typing
from collections import namedtuple
from .helpers import get_sheet_of_file, strip_excel_value, is_empty_excel_value
from .exceptions import BudgetParserError
from .helpers import get_sheet_of_file, is_empty_excel_value, strip_excel_value
ExcelStuff = typing.Any
T = typing.TypeVar("T")
EXPECTED_TABLE_HEADERS = [
"Nr.",
@ -36,17 +40,18 @@ BudgetData = namedtuple( @@ -36,17 +40,18 @@ BudgetData = namedtuple(
)
def _check_table_header(xl_row):
def _check_table_header(xl_row: ExcelStuff) -> None:
fields_ignore_none = (
("" if c is None else c) for c in xl_row.data[:NUM_EXPECTED_HEADERS]
)
fields_str = (str(c) for c in fields_ignore_none)
fields = [c.strip() for c in fields_str]
if fields != EXPECTED_TABLE_HEADERS:
raise BudgetParserError(f"unexpected headers: '{xl_row.data}'")
msg = f"unexpected headers: '{xl_row.data}'"
raise BudgetParserError(msg)
def _skip_empty_lines(rows):
def _skip_empty_lines(rows: ExcelStuff) -> typing.Iterable[T]:
for xl_row in rows:
first_cell = xl_row.data[0]
if is_empty_excel_value(first_cell):
@ -54,7 +59,7 @@ def _skip_empty_lines(rows): @@ -54,7 +59,7 @@ def _skip_empty_lines(rows):
yield xl_row
def _parse_data_table(rows):
def _parse_data_table(rows: ExcelStuff) -> BudgetData:
for xl_row in _skip_empty_lines(rows):
data = [
strip_excel_value(value)
@ -63,14 +68,14 @@ def _parse_data_table(rows): @@ -63,14 +68,14 @@ def _parse_data_table(rows):
yield BudgetData(xl_row.row, *data)
def parse_budget_data(xls_sheet):
def parse_budget_data(xls_sheet: ExcelStuff) -> list[BudgetData]:
"""parses the budget data"""
rows = (ExcelRow(i, v) for i, v in enumerate(xls_sheet.values, start=1))
_check_table_header(next(rows))
return list(_parse_data_table(rows))
def parse_budget_file(file_path):
def parse_budget_file(file_path: str) -> list[BudgetData]:
"""parses the budget file"""
sheet = get_sheet_of_file(file_path, sheet=None)
return parse_budget_data(sheet)

2
superx_budget/exceptions.py

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
""" Exceptions used in the Project """
"""Exceptions used in the Project"""
class SuperXBudgetError(ValueError):

32
superx_budget/helpers.py

@ -1,13 +1,16 @@ @@ -1,13 +1,16 @@
""" some helper functions """
"""some helper functions"""
from pathlib import Path
from typing import TypeVar
import openpyxl
ExcelItem = TypeVar("ExcelItem")
DEFAULT_RECIPIENTS = ["frey@imtek.de"]
def excel_value_as_number(value):
def excel_value_as_number(value: ExcelItem) -> float | int:
if value is None:
return 0
if isinstance(value, str):
@ -18,7 +21,7 @@ def excel_value_as_number(value): @@ -18,7 +21,7 @@ def excel_value_as_number(value):
return value
def get_sheet_of_file(excel_file, sheet=None):
def get_sheet_of_file(excel_file: str, sheet: str | None = None) -> ExcelItem:
"""returns a sheet from an excel FileCache
if name is set to None, the function returns the first sheet
@ -30,51 +33,52 @@ def get_sheet_of_file(excel_file, sheet=None): @@ -30,51 +33,52 @@ def get_sheet_of_file(excel_file, sheet=None):
return workbook[sheet]
def is_empty_excel_value(value):
def is_empty_excel_value(value: ExcelItem) -> bool:
"""is the cell value considered empty"""
if value is None:
return True
if isinstance(value, str) and value.strip() == "":
return True
return False
return isinstance(value, str) and value.strip() == ""
def strip_excel_value(value):
def strip_excel_value(value: ExcelItem) -> str | ExcelItem:
"""remove whitespace from an excel value if it is a string"""
if isinstance(value, str):
return value.strip()
return value
def is_budget_file_name(path_or_name):
def is_budget_file_name(path_or_name: str | Path) -> bool:
"""checks if a filename has the format "budget[...]-<year>.xlsx"""
path = Path(path_or_name)
if not path.suffix.lower() == ".xlsx":
if path.suffix.lower() != ".xlsx":
return False
if not path.name.lower().startswith("budget"):
return False
try:
return int(path.stem[-5:]) <= -2019
return int(path.stem[-5:]) <= -2019 # noqa: PLR2004
except ValueError:
pass
return False
def list_budget_files(folder):
def list_budget_files(folder: str | Path) -> list[Path]:
"""lists all files with the name "budget[...]-<year>.xlsx"""
files = (i for i in Path(folder).iterdir() if i.is_file())
visible = (i for i in files if not i.name.startswith("."))
return [i for i in visible if is_budget_file_name(i)]
def find_budget_file(folder, year):
def find_budget_file(folder: str | Path, year: str | int) -> Path | None:
"""searches for a file with the name "budget[...]-<year>.xlsx"""
for path in list_budget_files(folder):
if path.stem.endswith(f"-{year}"):
return path
return None
def find_recipients(folder, filename="recipients.txt"):
def find_recipients(
folder: str | Path, filename: str = "recipients.txt"
) -> list[str]:
"""finds the recipients of the budget list"""
file_path = folder / filename
if file_path.is_file():

6
superx_budget/overview.py

@ -66,11 +66,11 @@ class ProjectOverview: @@ -66,11 +66,11 @@ class ProjectOverview:
def _create_overview_map(budget_list):
"""returns a dictonary with project as key and overview as value"""
map = {}
mapping = {}
for budget_data in budget_list:
overview = ProjectOverview(budget_data)
map[str(overview.project)] = overview
return map
mapping[str(overview.project)] = overview
return mapping
def _filter_superx_material_expenses(superx_export):

24
superx_budget/pyramid/__init__.py

@ -1,31 +1,29 @@ @@ -1,31 +1,29 @@
""" Superx Budget GUI """
"""Superx Budget GUI"""
from pathlib import Path
from pyramid.view import notfound_view_config
from pyramid.authorization import Allow, Authenticated, Everyone
from pyramid.config import Configurator
from pyramid.session import JSONSerializer, SignedCookieSessionFactory
from pyramid.authorization import Allow, Everyone, Authenticated
from pyramid.httpexceptions import HTTPFound
from pyramid.session import JSONSerializer, SignedCookieSessionFactory
from pyramid.view import notfound_view_config
from ..overview import create_overview # noqa: F401
from ..exceptions import BudgetParserError, SuperXParserError # noqa: F401
from ..overview import create_overview # noqa: F401
XLSX_CONTENT_TYPE = "application/octet-stream"
class Root:
__acl__ = [(Allow, Everyone, "login"), (Allow, Authenticated, "view")]
__acl__ = [(Allow, Everyone, "login"), (Allow, Authenticated, "view")] # noqa: RUF012
def __init__(self, request):
pass
def main(global_config, **settings):
def main(global_config, **settings): # noqa: ARG001
"""This function returns a Pyramid WSGI application."""
with Configurator(settings=settings) as config:
session_factory = SignedCookieSessionFactory(
settings["session.secret"], serializer=JSONSerializer()
)
@ -34,7 +32,11 @@ def main(global_config, **settings): @@ -34,7 +32,11 @@ def main(global_config, **settings):
config.set_root_factory(Root)
config.add_request_method(
lambda r: Path(settings["budgets.dir"]), "budgets_dir", reify=True
lambda r: Path( # noqa: ARG005
settings["budgets.dir"]
),
"budgets_dir",
reify=True,
)
age = int(settings.get("static_views.cache_max_age", 0))
@ -49,5 +51,5 @@ def main(global_config, **settings): @@ -49,5 +51,5 @@ def main(global_config, **settings):
@notfound_view_config()
def not_found(context, request):
def not_found(context, request): # noqa: ARG001
return HTTPFound("/")

28
superx_budget/pyramid/overview.py

@ -1,17 +1,17 @@ @@ -1,17 +1,17 @@
""" Views for the create overview part """
"""Views for the create overview part"""
from tempfile import NamedTemporaryFile
from pyramid.view import view_config
from pyramid.httpexceptions import HTTPFound
from pyramid_mailer.message import Message, Attachment
from pyramid.view import view_config
from pyramid_mailer.message import Attachment, Message
from . import XLSX_CONTENT_TYPE, Root
from ..budget import parse_budget_file
from ..exceptions import BudgetParserError, SuperXParserError
from ..helpers import find_budget_file, find_recipients, get_sheet_of_file
from ..overview import create_overview
from ..superx import parse_exported_file
from ..helpers import find_recipients, find_budget_file, get_sheet_of_file
from ..overview import create_overview # noqa: F401
from ..exceptions import BudgetParserError, SuperXParserError # noqa: F401
from . import XLSX_CONTENT_TYPE, Root
MAIL_MESSAGE_BODY = """Hallo an Alle,
@ -35,10 +35,10 @@ def _map_from_form_data(request, prefix): @@ -35,10 +35,10 @@ def _map_from_form_data(request, prefix):
row_str = key.split("-")[-1]
row = int(row_str)
try:
value = float(value)
as_number = float(value)
except ValueError:
value = 0
result[row] = value
as_number = 0
result[row] = as_number
return result
@ -48,7 +48,7 @@ def _map_from_form_data(request, prefix): @@ -48,7 +48,7 @@ def _map_from_form_data(request, prefix):
renderer="superx_budget:pyramid/templates/start.jinja2",
permission="view",
)
def index(context, request):
def index(context, request): # noqa: ARG001
return {}
@ -58,7 +58,7 @@ def index(context, request): @@ -58,7 +58,7 @@ def index(context, request):
renderer="superx_budget:pyramid/templates/overview.jinja2",
permission="view",
)
def superx_upload(context, request):
def superx_upload(context, request): # noqa: ARG001
upload = request.POST.get("superx")
if upload == b"" or not upload.filename.endswith(".xlsx"):
@ -122,7 +122,7 @@ def superx_upload(context, request): @@ -122,7 +122,7 @@ def superx_upload(context, request):
renderer="superx_budget:pyramid/templates/sent.jinja2",
permission="view",
)
def send_overview(context, request):
def send_overview(context, request): # noqa: ARG001
export_date = request.POST.get("export_date").strip()
tmp_recipients = request.POST.get("recipients").strip()
recipients = tmp_recipients.splitlines()
@ -165,7 +165,7 @@ def send_overview(context, request): @@ -165,7 +165,7 @@ def send_overview(context, request):
xls_name = f"{export_date}-Budget-Overview-{budget_year}.xlsx"
with NamedTemporaryFile() as tmp:
sheet._parent.save(tmp.name)
sheet._parent.save(tmp.name) # noqa: SLF001
tmp.seek(0)
attachment = Attachment(xls_name, XLSX_CONTENT_TYPE, tmp)
message.attach(attachment)

13
superx_budget/pyramid/security.py

@ -1,9 +1,9 @@ @@ -1,9 +1,9 @@
from passlib.hash import argon2
from pyramid.view import view_config, forbidden_view_config
from pyramid.security import forget, remember
from pyramid.authorization import ACLAuthorizationPolicy
from pyramid.authentication import AuthTktAuthenticationPolicy
from pyramid.authorization import ACLAuthorizationPolicy
from pyramid.httpexceptions import HTTPFound
from pyramid.security import forget, remember
from pyramid.view import forbidden_view_config, view_config
from . import Root
@ -15,6 +15,7 @@ class MyAuthenticationPolicy(AuthTktAuthenticationPolicy): @@ -15,6 +15,7 @@ class MyAuthenticationPolicy(AuthTktAuthenticationPolicy):
user = request.user
if user is not None:
return AUTHENTICATED_USER_ID
return None
def get_user(request):
@ -22,7 +23,7 @@ def get_user(request): @@ -22,7 +23,7 @@ def get_user(request):
@forbidden_view_config(renderer="superx_budget:pyramid/templates/login.jinja2")
def forbidden_view(request):
def forbidden_view(request): # noqa: ARG001
return {"error": False}
@ -54,11 +55,11 @@ def includeme(config): @@ -54,11 +55,11 @@ def includeme(config):
config.set_authentication_policy(authn_policy)
config.set_authorization_policy(ACLAuthorizationPolicy())
hashes = [hash for hash in settings["pwd.db"].splitlines() if hash]
hashes = [hashed for hashed in settings["pwd.db"].splitlines() if hashed]
def check_password(request):
password = request.POST.get("password", "")
return any(argon2.verify(password, hash) for hash in hashes)
return any(argon2.verify(password, hashed) for hashed in hashes)
config.add_request_method(check_password, "check_password")
config.add_request_method(get_user, "user", reify=True)

16
superx_budget/pyramid/templates.py

@ -1,16 +1,16 @@ @@ -1,16 +1,16 @@
""" Views for the templates part """
"""Views for the templates part"""
from pathlib import Path
from pyramid.view import view_config
from pyramid.response import FileResponse
from pyramid.httpexceptions import HTTPFound
from pyramid.response import FileResponse
from pyramid.view import view_config
from . import XLSX_CONTENT_TYPE, Root
from ..budget import parse_budget_file
from ..helpers import list_budget_files, is_budget_file_name
from ..overview import create_overview # noqa: F401
from ..exceptions import BudgetParserError, SuperXParserError # noqa: F401
from ..helpers import is_budget_file_name, list_budget_files
from ..overview import create_overview # noqa: F401
from . import XLSX_CONTENT_TYPE, Root
@view_config(
@ -20,7 +20,7 @@ from ..exceptions import BudgetParserError, SuperXParserError # noqa: F401 @@ -20,7 +20,7 @@ from ..exceptions import BudgetParserError, SuperXParserError # noqa: F401
renderer="superx_budget:pyramid/templates/templates.jinja2",
permission="view",
)
def templates(context, request):
def templates(context, request): # noqa: ARG001
if "f" in request.GET:
file_name = request.GET["f"]
file_path = request.budgets_dir / file_name
@ -50,7 +50,7 @@ def templates(context, request): @@ -50,7 +50,7 @@ def templates(context, request):
renderer="superx_budget:pyramid/templates/templates.jinja2",
permission="view",
)
def templates_update(context, request):
def templates_update(context, request): # noqa: ARG001
upload = request.POST.get("budget")
if upload == b"" or not is_budget_file_name(upload.filename):

22
superx_budget/superx.py

@ -1,10 +1,10 @@ @@ -1,10 +1,10 @@
""" SuperX Parser """
"""SuperX Parser"""
from datetime import datetime
from collections import namedtuple
from datetime import datetime
from .helpers import get_sheet_of_file, strip_excel_value
from .exceptions import SuperXParserError
from .helpers import get_sheet_of_file, strip_excel_value
EXPECTED_HEADLINE = "Verwendungsnachweis und Kassenstand SAP"
EXPECTED_METADATA_KEYS = {"Haushaltsjahr", "Stand", "Gruppierung"}
@ -36,7 +36,8 @@ def _check_export_headline(row): @@ -36,7 +36,8 @@ def _check_export_headline(row):
"""checks the first line of the excel data if it's what we'd expect"""
headline = row[0]
if headline != EXPECTED_HEADLINE:
raise SuperXParserError(f"unexpected headline: '{headline}'")
msg = f"unexpected headline: '{headline}'"
raise SuperXParserError(msg)
def _get_export_metadata(row):
@ -46,11 +47,11 @@ def _get_export_metadata(row): @@ -46,11 +47,11 @@ def _get_export_metadata(row):
parts = [entry.split(":", 1) for entry in entries]
metadata = {key.strip(): value.strip() for key, value in parts}
if EXPECTED_METADATA_KEYS - set(metadata.keys()):
raise SuperXParserError(f"unexpected metadata: '{data}'")
msg = f"unexpected metadata: '{data}'"
raise SuperXParserError(msg)
if metadata["Gruppierung"] != EXPECTED_EXPORT_GROUPING:
raise SuperXParserError(
f"unexpected grouping: {metadata['Gruppierung']}"
)
msg = f"unexpected grouping: {metadata['Gruppierung']}"
raise SuperXParserError(msg)
date_part, *rest = metadata["Stand"].split(",")
return SuperXResult(
metadata["Haushaltsjahr"],
@ -66,7 +67,8 @@ def _skip_export_data_until_table_header(rows): @@ -66,7 +67,8 @@ def _skip_export_data_until_table_header(rows):
if first_cell == EXPECTED_DATA_TABLE_HEADER:
break
else:
raise SuperXParserError("could not find table header")
msg = "could not find table header"
raise SuperXParserError(msg)
def _parse_data_table(rows):
@ -80,7 +82,7 @@ def _parse_data_table(rows): @@ -80,7 +82,7 @@ def _parse_data_table(rows):
def parse_export_data(xls_sheet):
"""parses the exported superx data"""
rows = xls_sheet.values
rows = xls_sheet.values # noqa: PD011
_check_export_headline(next(rows))
metadata = _get_export_metadata(next(rows))
_skip_export_data_until_table_header(rows)

10
tests/conftest.py

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
""" Global test fixtures and Mocks """
"""Global test fixtures and Mocks"""
from pathlib import Path
@ -17,7 +17,7 @@ class MockWorkbookSheet: @@ -17,7 +17,7 @@ class MockWorkbookSheet:
@pytest.fixture
def example_root(request):
root_dir = Path(request.config.rootdir)
yield root_dir / "test_data"
return root_dir / "test_data"
@pytest.fixture
@ -29,14 +29,14 @@ def budget_example_file(example_root): @@ -29,14 +29,14 @@ def budget_example_file(example_root):
def budget_example_workbook(budget_example_file):
import openpyxl
yield openpyxl.open(budget_example_file)
return openpyxl.open(budget_example_file)
@pytest.fixture
def budget_example_sheet(budget_example_workbook):
sheets = budget_example_workbook.sheetnames
first = sheets[0]
yield budget_example_workbook[first]
return budget_example_workbook[first]
@pytest.fixture
@ -48,4 +48,4 @@ def superx_example_file(example_root): @@ -48,4 +48,4 @@ def superx_example_file(example_root):
def superx_example_workbook(superx_example_file):
import openpyxl
yield openpyxl.open(superx_example_file)
return openpyxl.open(superx_example_file)

20
tests/test_helpers.py

@ -2,7 +2,7 @@ import pytest @@ -2,7 +2,7 @@ import pytest
@pytest.mark.parametrize(
"input,expected",
("given", "expected"),
[
("a", False),
("", True),
@ -13,16 +13,16 @@ import pytest @@ -13,16 +13,16 @@ import pytest
(2.2, False),
],
)
def test_is_empty_excel_value(input, expected):
def test_is_empty_excel_value(given, expected):
from superx_budget.helpers import is_empty_excel_value
result = is_empty_excel_value(input)
result = is_empty_excel_value(given)
assert result == expected
@pytest.mark.parametrize(
"input,expected",
("given", "expected"),
[
("a", "a"),
("", ""),
@ -33,10 +33,10 @@ def test_is_empty_excel_value(input, expected): @@ -33,10 +33,10 @@ def test_is_empty_excel_value(input, expected):
(2.2, 2.2),
],
)
def test_strip_excel_value(input, expected):
def test_strip_excel_value(given, expected):
from superx_budget.helpers import strip_excel_value
result = strip_excel_value(input)
result = strip_excel_value(given)
assert result == expected
@ -62,7 +62,7 @@ def test_get_sheet_of_file_named(budget_example_file): @@ -62,7 +62,7 @@ def test_get_sheet_of_file_named(budget_example_file):
@pytest.mark.parametrize(
"input,expected",
("given", "expected"),
[
(None, 0),
("", 0),
@ -73,16 +73,16 @@ def test_get_sheet_of_file_named(budget_example_file): @@ -73,16 +73,16 @@ def test_get_sheet_of_file_named(budget_example_file):
(2.4, 2.4),
],
)
def test_excel_value_as_number(input, expected):
def test_excel_value_as_number(given, expected):
from superx_budget.helpers import excel_value_as_number
result = excel_value_as_number(input)
result = excel_value_as_number(given)
assert result == expected
@pytest.mark.parametrize(
"name,expected",
("name", "expected"),
[
("budget-2019.xlsx", True),
("budget-template-2020.xlsx", True),

12
tests/test_overview.py

@ -17,7 +17,7 @@ def example_budget_data(): @@ -17,7 +17,7 @@ def example_budget_data():
0,
)
yield example
return example # noqa: RET504
def test_project_overview_init(example_budget_data):
@ -46,7 +46,7 @@ def test_project_overview_row_property(example_budget_data): @@ -46,7 +46,7 @@ def test_project_overview_row_property(example_budget_data):
def test_project_overview_add(example_budget_data):
from superx_budget.overview import ProjectOverview, OverviewBudgetEntry
from superx_budget.overview import OverviewBudgetEntry, ProjectOverview
over = ProjectOverview(example_budget_data)
over.add("Sachmittel", "Obligo", -100)
@ -94,11 +94,11 @@ def test_create_overview_map(budget_example_file): @@ -94,11 +94,11 @@ def test_create_overview_map(budget_example_file):
def test_create_entries_from_export(budget_example_file, superx_example_file):
from superx_budget.budget import parse_budget_file
from superx_budget.superx import parse_exported_file
from superx_budget.overview import (
_create_overview_map,
_create_entries_from_superx,
_create_overview_map,
)
from superx_budget.superx import parse_exported_file
superx_data = parse_exported_file(superx_example_file)
budget_data = parse_budget_file(budget_example_file)
@ -111,11 +111,11 @@ def test_create_entries_from_export(budget_example_file, superx_example_file): @@ -111,11 +111,11 @@ def test_create_entries_from_export(budget_example_file, superx_example_file):
def test_filter_superx_material_expenses(superx_example_file):
from superx_budget.superx import parse_exported_file
from superx_budget.overview import (
VALID_MATERIAL_IDS,
_filter_superx_material_expenses,
)
from superx_budget.superx import parse_exported_file
superx_data = parse_exported_file(superx_example_file)
result = list(_filter_superx_material_expenses(superx_data))
@ -127,8 +127,8 @@ def test_filter_superx_material_expenses(superx_example_file): @@ -127,8 +127,8 @@ def test_filter_superx_material_expenses(superx_example_file):
def test_create_overview(budget_example_file, superx_example_file):
from superx_budget.budget import parse_budget_file
from superx_budget.superx import parse_exported_file
from superx_budget.overview import create_overview
from superx_budget.superx import parse_exported_file
superx_data = parse_exported_file(superx_example_file)
budget_data = parse_budget_file(budget_example_file)

12
tests/test_superx_parser.py

@ -1,11 +1,11 @@ @@ -1,11 +1,11 @@
""" Stub file for testing the project """
"""Stub file for testing the project"""
import pytest
def test_check_export_headline():
from superx_budget.superx import _check_export_headline
from superx_budget.exceptions import SuperXParserError
from superx_budget.superx import _check_export_headline
row = ["nomatching header"]
@ -42,9 +42,7 @@ def test_get_export_metadata_raises_error(faulty_data): @@ -42,9 +42,7 @@ def test_get_export_metadata_raises_error(faulty_data):
row = [faulty_data]
with pytest.raises(
ValueError
): # SuperXParserError is a subclass of ValueError
with pytest.raises(ValueError): # noqa: PT011
_get_export_metadata(row)
@ -60,8 +58,8 @@ def test_skip_export_data_until_table_header_ok(): @@ -60,8 +58,8 @@ def test_skip_export_data_until_table_header_ok():
def test_skip_export_data_until_table_header_raises_error():
from superx_budget.superx import _skip_export_data_until_table_header
from superx_budget.exceptions import SuperXParserError
from superx_budget.superx import _skip_export_data_until_table_header
rows = [[""], [""], ["Keine Kostenstelle"], ["Daten"]]
iterator = iter(rows)
@ -73,7 +71,7 @@ def test_parse_data_table(): @@ -73,7 +71,7 @@ def test_parse_data_table():
from superx_budget.superx import _parse_data_table
rows = [
["A "] + list("BCDEFGHIJ"),
["A ", *list("BCDEFGHIJ")],
["" for i in range(10)],
list("qrstuvwxyzX"), # one column more
]

Loading…
Cancel
Save