diff --git a/.github/workflows/coordo-py.yml b/.github/workflows/coordo-py.yml index 5bbb328..462b85a 100644 --- a/.github/workflows/coordo-py.yml +++ b/.github/workflows/coordo-py.yml @@ -34,3 +34,6 @@ jobs: - name: Run tests run: uv run test.py + + - name: Run pytest + run: uv run pytest diff --git a/coordo-py/pyproject.toml b/coordo-py/pyproject.toml index 61b1534..6f05be6 100644 --- a/coordo-py/pyproject.toml +++ b/coordo-py/pyproject.toml @@ -28,7 +28,12 @@ coordo = "coordo.cli:app" [tool.setuptools.package-data] "coordo" = ["static/*", "**/*.sql"] +[tool.pytest.ini_options] +testpaths = ["tests"] +addopts = ["-s"] + [dependency-groups] dev = [ "ruff>=0.15.8", + "pytest>=8.0", ] diff --git a/coordo-py/tests/__init__.py b/coordo-py/tests/__init__.py new file mode 100644 index 0000000..e5a1d76 --- /dev/null +++ b/coordo-py/tests/__init__.py @@ -0,0 +1,2 @@ +# Copyright COORDONNÉES 2025, 2026 +# SPDX-License-Identifier: MPL-2.0 \ No newline at end of file diff --git a/coordo-py/tests/conftest.py b/coordo-py/tests/conftest.py new file mode 100644 index 0000000..37ed756 --- /dev/null +++ b/coordo-py/tests/conftest.py @@ -0,0 +1,24 @@ +# Copyright COORDONNÉES 2025, 2026 +# SPDX-License-Identifier: MPL-2.0 + +import pytest +from pathlib import Path + +DATA_DIR = Path("tests/test_data") +INVENTORY_DIR = DATA_DIR / "inventory" + +@pytest.fixture +def inventory_package(): + return "catalog/inventory" + +@pytest.fixture +def inventory_inquiry(): + return INVENTORY_DIR / "inquiry.xlsx" + +@pytest.fixture +def inventory_data(): + return INVENTORY_DIR / "data.xlsx" + +@pytest.fixture +def inventory_file(): + return INVENTORY_DIR / "file.csv" \ No newline at end of file diff --git a/coordo-py/tests/test_cli.py b/coordo-py/tests/test_cli.py new file mode 100644 index 0000000..67fd1fc --- /dev/null +++ b/coordo-py/tests/test_cli.py @@ -0,0 +1,33 @@ +# Copyright COORDONNÉES 2025, 2026 +# SPDX-License-Identifier: MPL-2.0 + +import shutil +from typer.testing import CliRunner +from coordo.cli import app + +runner = CliRunner() + +def get_output_and_check_exitcode(result): + print(result.stdout_bytes.decode()) + assert result.exit_code == 0 + +def test_add_data_to_package(inventory_package, inventory_inquiry, inventory_data, inventory_file): + """ + Test the following workflow: + - Load data from a kobotoolbox inquiry and a file into a package. + - Add a foreign key between two fields. + - Remove the foreign key. + - Add the foreign key again. + """ + result = runner.invoke(app, ["load", "kobotoolbox", str(inventory_inquiry), str(inventory_data), "--package", inventory_package, "--action", "add"]) + get_output_and_check_exitcode(result) + result = runner.invoke(app, ["load", "file", str(inventory_file), "--package", inventory_package, "--action", "add"]) + get_output_and_check_exitcode(result) + result = runner.invoke(app, ["add-foreignkey", "ind.ess_arb", "file.ess_arb", "--package", inventory_package]) + get_output_and_check_exitcode(result) + result = runner.invoke(app, ["remove-foreignkey", "ind.ess_arb", "file.ess_arb", "--package", inventory_package]) + get_output_and_check_exitcode(result) + result = runner.invoke(app, ["add-foreignkey", "ind.ess_arb", "file.ess_arb", "--package", inventory_package]) + get_output_and_check_exitcode(result) + print(f"Removing package '{inventory_package}'") + shutil.rmtree(inventory_package) \ No newline at end of file diff --git a/coordo-py/tests/test_data/inventory/data.xlsx b/coordo-py/tests/test_data/inventory/data.xlsx new file mode 100644 index 0000000..cb13bd6 Binary files /dev/null and b/coordo-py/tests/test_data/inventory/data.xlsx differ diff --git a/coordo-py/tests/test_data/inventory/file.csv b/coordo-py/tests/test_data/inventory/file.csv new file mode 100644 index 0000000..e2ef7b7 --- /dev/null +++ b/coordo-py/tests/test_data/inventory/file.csv @@ -0,0 +1,37 @@ +ess_arb,value +1,0.422 +2,0.694 +4,0.607 +5,0.607 +7,0.56 +8,0.738 +9,0.723 +10,0.56 +16,0.642 +25,0.8 +33,0.636 +35,0.627 +37,0.56 +39,0.886 +58,0.56 +67,0.56 +70,0.682 +72,0.736 +77,0.56 +93,0.854 +96,0.8 +105,0.681 +111,0.671 +127,0.55 +133,0.681 +145,0.465 +166,0.56 +173,0.56 +187,0.56 +194,0.641 +195,0.664 +198,0.56 +213,0.49 +243,0.56 +248,0.646 +251,0.56 diff --git a/coordo-py/tests/test_data/inventory/inquiry.xlsx b/coordo-py/tests/test_data/inventory/inquiry.xlsx new file mode 100644 index 0000000..73db790 Binary files /dev/null and b/coordo-py/tests/test_data/inventory/inquiry.xlsx differ diff --git a/coordo-py/uv.lock b/coordo-py/uv.lock index 76198da..4b6488a 100644 --- a/coordo-py/uv.lock +++ b/coordo-py/uv.lock @@ -225,6 +225,7 @@ dependencies = [ [package.dev-dependencies] dev = [ + { name = "pytest" }, { name = "ruff" }, ] @@ -249,7 +250,10 @@ requires-dist = [ ] [package.metadata.requires-dev] -dev = [{ name = "ruff", specifier = ">=0.15.8" }] +dev = [ + { name = "pytest", specifier = ">=8.0" }, + { name = "ruff", specifier = ">=0.15.8" }, +] [[package]] name = "dateparser" @@ -555,6 +559,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, ] +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + [[package]] name = "itsdangerous" version = "2.2.0" @@ -984,6 +997,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e6/3f/a80ac00acbc6b35166b42850e98a4f466e2c0d9c64054161ba9620f95680/pandas-3.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:1c39eab3ad38f2d7a249095f0a3d8f8c22cc0f847e98ccf5bbe732b272e2d9fa", size = 9441003, upload-time = "2026-01-21T15:52:02.281Z" }, ] +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + [[package]] name = "propcache" version = "0.4.1" @@ -1395,6 +1417,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/15/73/a7141a1a0559bf1a7aa42a11c879ceb19f02f5c6c371c6d57fd86cefd4d1/pyproj-3.7.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d9d25bae416a24397e0d85739f84d323b55f6511e45a522dd7d7eae70d10c7e4", size = 6391844, upload-time = "2025-08-14T12:05:40.745Z" }, ] +[[package]] +name = "pytest" +version = "9.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, +] + [[package]] name = "python-dateutil" version = "2.9.0.post0"