From 40f2f49d24d05363ff61950b6f590b768c95c50c Mon Sep 17 00:00:00 2001 From: Stephen Thompson Date: Tue, 9 Dec 2025 10:22:40 +0000 Subject: [PATCH 1/6] Added failing test --- pyproject.toml | 1 + tests/__init__.py | 0 tests/test_file_writer.py | 24 +++++++++++++++ uv.lock | 63 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+) create mode 100644 tests/__init__.py create mode 100644 tests/test_file_writer.py diff --git a/pyproject.toml b/pyproject.toml index fc9c7bb..153c6e9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,6 +8,7 @@ dependencies = [ "pika>=1.3.2", "pre-commit>=4.5.0", "psycopg2-binary>=2.9.11", + "pytest>=9.0.2", ] [project.scripts] diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_file_writer.py b/tests/test_file_writer.py new file mode 100644 index 0000000..53d26e4 --- /dev/null +++ b/tests/test_file_writer.py @@ -0,0 +1,24 @@ +import pytest +from waveform_controller.csv_writer import create_file_name +from datetime import datetime, timezone + + +@pytest.mark.parametrize( + "units, expected_filename", + [ + ("uV", "2025-01-01.12345678.11.uV.csv"), + ("mL/s", "2025-01-01.12345678.11.mL/s.csv"), + ], +) +def test_create_file_name_handles_units(units, expected_filename, tmp_path): + sourceSystem = "11" + observationTime = datetime(2025, 1, 1, tzinfo=timezone.utc) + csn = "12345678" + + filename = create_file_name(sourceSystem, observationTime, csn, units) + + assert filename == expected_filename + + # check we can write to it + with open(f"{tmp_path}/{filename}", "w") as fileout: + fileout.write("Test string") diff --git a/uv.lock b/uv.lock index a953717..922bbd2 100644 --- a/uv.lock +++ b/uv.lock @@ -11,6 +11,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" }, ] +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + [[package]] name = "distlib" version = "0.4.0" @@ -38,6 +47,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0f/1c/e5fd8f973d4f375adb21565739498e2e9a1e54c858a97b9a8ccfdc81da9b/identify-2.6.15-py2.py3-none-any.whl", hash = "sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757", size = 99183, upload-time = "2025-10-02T17:43:39.137Z" }, ] +[[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 = "nodeenv" version = "1.9.1" @@ -47,6 +65,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, ] +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + [[package]] name = "pika" version = "1.3.2" @@ -65,6 +92,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3", size = 18651, upload-time = "2025-10-08T17:44:47.223Z" }, ] +[[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 = "pre-commit" version = "4.5.0" @@ -133,6 +169,31 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e1/36/9c0c326fe3a4227953dfb29f5d0c8ae3b8eb8c1cd2967aa569f50cb3c61f/psycopg2_binary-2.9.11-cp314-cp314-win_amd64.whl", hash = "sha256:4012c9c954dfaccd28f94e84ab9f94e12df76b4afb22331b1f0d3154893a6316", size = 2803913, upload-time = "2025-10-10T11:13:57.058Z" }, ] +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pytest" +version = "9.0.2" +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/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" }, +] + [[package]] name = "pyyaml" version = "6.0.3" @@ -210,6 +271,7 @@ dependencies = [ { name = "pika" }, { name = "pre-commit" }, { name = "psycopg2-binary" }, + { name = "pytest" }, ] [package.metadata] @@ -217,4 +279,5 @@ requires-dist = [ { name = "pika", specifier = ">=1.3.2" }, { name = "pre-commit", specifier = ">=4.5.0" }, { name = "psycopg2-binary", specifier = ">=2.9.11" }, + { name = "pytest", specifier = ">=9.0.2" }, ] From 41d9dceaa7236da3146aaaf864172107c4d0573c Mon Sep 17 00:00:00 2001 From: Stephen Thompson Date: Tue, 9 Dec 2025 10:25:55 +0000 Subject: [PATCH 2/6] Added ci --- .github/workflows/pytest.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/pytest.yml diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml new file mode 100644 index 0000000..65af8da --- /dev/null +++ b/.github/workflows/pytest.yml @@ -0,0 +1,28 @@ +name: Run Python tests + +on: + push: + branches: [main, dev] + pull_request: + branches: [main, dev] + types: ["opened", "reopened", "synchronize", "ready_for_review", "draft"] + workflow_dispatch: + +jobs: + build: + name: Run tests + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.11"] + + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: pip install pytest + - name: run pytest + run: pytest tests/* From b4b5b20b7dadfe3eb86775c54745b9976bba0e3b Mon Sep 17 00:00:00 2001 From: Stephen Thompson Date: Tue, 9 Dec 2025 10:31:13 +0000 Subject: [PATCH 3/6] Fix with string substition --- tests/test_file_writer.py | 2 +- waveform_controller/csv_writer.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_file_writer.py b/tests/test_file_writer.py index 53d26e4..514e8e3 100644 --- a/tests/test_file_writer.py +++ b/tests/test_file_writer.py @@ -7,7 +7,7 @@ "units, expected_filename", [ ("uV", "2025-01-01.12345678.11.uV.csv"), - ("mL/s", "2025-01-01.12345678.11.mL/s.csv"), + ("mL/s", "2025-01-01.12345678.11.mLps.csv"), ], ) def test_create_file_name_handles_units(units, expected_filename, tmp_path): diff --git a/waveform_controller/csv_writer.py b/waveform_controller/csv_writer.py index 3b8a9b1..6a0a3b5 100644 --- a/waveform_controller/csv_writer.py +++ b/waveform_controller/csv_writer.py @@ -11,6 +11,7 @@ def create_file_name( """Create a unique file name based on the patient contact serial number (csn) the date, and the source system.""" datestring = observationTime.strftime("%Y-%m-%d") + units = units.replace("/", "p") return f"{datestring}.{csn}.{sourceSystem}.{units}.csv" From 702d818c1878c67e5b735a3368dc0f7b72285fa1 Mon Sep 17 00:00:00 2001 From: Stephen Thompson Date: Tue, 9 Dec 2025 11:19:36 +0000 Subject: [PATCH 4/6] Also change % to percent --- tests/test_file_writer.py | 1 + waveform_controller/csv_writer.py | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/test_file_writer.py b/tests/test_file_writer.py index 514e8e3..b1ccf2c 100644 --- a/tests/test_file_writer.py +++ b/tests/test_file_writer.py @@ -8,6 +8,7 @@ [ ("uV", "2025-01-01.12345678.11.uV.csv"), ("mL/s", "2025-01-01.12345678.11.mLps.csv"), + ("%", "2025-01-01.12345678.11.percent.csv"), ], ) def test_create_file_name_handles_units(units, expected_filename, tmp_path): diff --git a/waveform_controller/csv_writer.py b/waveform_controller/csv_writer.py index 6a0a3b5..0b0483b 100644 --- a/waveform_controller/csv_writer.py +++ b/waveform_controller/csv_writer.py @@ -12,6 +12,7 @@ def create_file_name( (csn) the date, and the source system.""" datestring = observationTime.strftime("%Y-%m-%d") units = units.replace("/", "p") + units = units.replace("%", "percent") return f"{datestring}.{csn}.{sourceSystem}.{units}.csv" From e2d88ea4a86f37dbf57e4ae6212ff8ca461b21c6 Mon Sep 17 00:00:00 2001 From: Stephen Thompson Date: Tue, 9 Dec 2025 11:39:32 +0000 Subject: [PATCH 5/6] With uv --- .github/workflows/pytest.yml | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 65af8da..a1adbb9 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -12,17 +12,15 @@ jobs: build: name: Run tests runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.11"] steps: - - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: pip install pytest - - name: run pytest - run: pytest tests/* + - uses: actions/checkout@v5 + - name: Install uv + uses: astral-sh/setup-uv@v7 + + - name: Install the project + run: uv sync --locked --all-extras --dev + + - name: Run tests + # For example, using `pytest` + run: uv run pytest tests From 338af4ea068fb93ef4e3c9a74fef47e3ea00c607 Mon Sep 17 00:00:00 2001 From: Stephen Thompson Date: Tue, 9 Dec 2025 11:43:55 +0000 Subject: [PATCH 6/6] Tidy workflow --- .github/workflows/pytest.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index a1adbb9..e85121a 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -1,4 +1,4 @@ -name: Run Python tests +name: Run pytest on: push: @@ -10,7 +10,7 @@ on: jobs: build: - name: Run tests + name: Run pytest runs-on: ubuntu-latest steps: @@ -18,9 +18,8 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@v7 - - name: Install the project + - name: Install dependencies run: uv sync --locked --all-extras --dev - - name: Run tests - # For example, using `pytest` + - name: Run the tests run: uv run pytest tests