From 5780947fe67b3eb45e4e01dddf7a04b103c8ac71 Mon Sep 17 00:00:00 2001 From: sneakers-the-rat Date: Wed, 14 Aug 2024 00:09:24 -0700 Subject: [PATCH] indexing tests, fix for pytest 8, logging tests --- nwb_linkml/pdm.lock | 33 ++++++++-------- nwb_linkml/pyproject.toml | 5 +-- nwb_linkml/src/nwb_linkml/maps/hdmf.py | 24 ------------ nwb_linkml/tests/test_includes/test_hdmf.py | 43 +++++++++++++++++++-- nwb_linkml/tests/test_logging.py | 35 +++++++++++++++++ 5 files changed, 93 insertions(+), 47 deletions(-) delete mode 100644 nwb_linkml/src/nwb_linkml/maps/hdmf.py create mode 100644 nwb_linkml/tests/test_logging.py diff --git a/nwb_linkml/pdm.lock b/nwb_linkml/pdm.lock index 3482eac..bea21e9 100644 --- a/nwb_linkml/pdm.lock +++ b/nwb_linkml/pdm.lock @@ -5,7 +5,7 @@ groups = ["default", "dev", "plot", "tests"] strategy = ["inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:20f4f69a117fab515291f53ff39dfd1e13e3c8cbd399f1f7ce308cbea7deeaf0" +content_hash = "sha256:d9e9b2a7f48f3db3e59cd58907a18aa69f91595d07eca53be0bf53b5fb2ba990" [[metadata.targets]] requires_python = ">=3.10,<3.13" @@ -70,7 +70,7 @@ name = "black" version = "24.8.0" requires_python = ">=3.8" summary = "The uncompromising code formatter." -groups = ["default", "dev"] +groups = ["default"] dependencies = [ "click>=8.0.0", "mypy-extensions>=0.4.3", @@ -219,7 +219,7 @@ name = "click" version = "8.1.7" requires_python = ">=3.7" summary = "Composable command line interface toolkit" -groups = ["default", "dev", "plot"] +groups = ["default", "plot"] dependencies = [ "colorama; platform_system == \"Windows\"", "importlib-metadata; python_version < \"3.8\"", @@ -512,7 +512,7 @@ version = "3.0.3" requires_python = ">=3.7" summary = "Lightweight in-process concurrent programming" groups = ["default"] -marker = "(platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\") and python_version < \"3.13\"" +marker = "platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\"" files = [ {file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"}, {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881"}, @@ -954,7 +954,7 @@ name = "mypy-extensions" version = "1.0.0" requires_python = ">=3.5" summary = "Type system extensions for programs checked with the mypy type checker." -groups = ["default", "dev"] +groups = ["default"] files = [ {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, @@ -1132,7 +1132,7 @@ name = "pathspec" version = "0.12.1" requires_python = ">=3.8" summary = "Utility library for gitignore style pattern matching of file paths." -groups = ["default", "dev"] +groups = ["default"] files = [ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, @@ -1385,22 +1385,21 @@ files = [ [[package]] name = "pytest" -version = "7.4.4" -requires_python = ">=3.7" +version = "8.3.2" +requires_python = ">=3.8" summary = "pytest: simple powerful testing with Python" groups = ["default", "dev", "tests"] dependencies = [ "colorama; sys_platform == \"win32\"", "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"", - "importlib-metadata>=0.12; python_version < \"3.8\"", "iniconfig", "packaging", - "pluggy<2.0,>=0.12", - "tomli>=1.0.0; python_version < \"3.11\"", + "pluggy<2,>=1.5", + "tomli>=1; python_version < \"3.11\"", ] files = [ - {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, - {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, + {file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"}, + {file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"}, ] [[package]] @@ -1759,7 +1758,7 @@ version = "0.2.8" requires_python = ">=3.6" summary = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" groups = ["default"] -marker = "platform_python_implementation == \"CPython\" and python_version < \"3.13\"" +marker = "platform_python_implementation == \"CPython\"" files = [ {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"}, @@ -1932,13 +1931,13 @@ files = [ [[package]] name = "sybil" -version = "5.0.3" +version = "6.1.1" requires_python = ">=3.7" summary = "Automated testing for the examples in your code and documentation." groups = ["dev", "tests"] files = [ - {file = "sybil-5.0.3-py3-none-any.whl", hash = "sha256:6f3c30822169895c4fb34c8366bdb132cf62bb68fb1d03d2ebb05282eab08c95"}, - {file = "sybil-5.0.3.tar.gz", hash = "sha256:20dfe3a35a8d1ffcb4311434d1abf38c030c91064d75ff6b56ddd1060e08e758"}, + {file = "sybil-6.1.1-py3-none-any.whl", hash = "sha256:04ae5e17997bc5166ba3da0d6244767c397e129f399a1aa23c89b30a704fec2c"}, + {file = "sybil-6.1.1.tar.gz", hash = "sha256:8fb4f2c3582d1fe6705d1ae3a31f93fec7619f634940a8fcbf5d1b7d18183917"}, ] [[package]] diff --git a/nwb_linkml/pyproject.toml b/nwb_linkml/pyproject.toml index f149733..f603a55 100644 --- a/nwb_linkml/pyproject.toml +++ b/nwb_linkml/pyproject.toml @@ -37,16 +37,15 @@ plot = [ ] tests = [ "nwb-linkml", - "pytest<8.0.0,>=7.4.0", + "pytest>=8.0.0", "pytest-depends<2.0.0,>=1.0.1", "pytest-cov<5.0.0,>=4.1.0", - "sybil<6.0.0,>=5.0.3", + "sybil>=6.0.3", "requests-cache>=1.2.1", ] dev = [ "nwb-linkml[tests]", "ruff>=0.5.0", - "black>=24.4.2", ] [tool.pdm] diff --git a/nwb_linkml/src/nwb_linkml/maps/hdmf.py b/nwb_linkml/src/nwb_linkml/maps/hdmf.py deleted file mode 100644 index 3c52b22..0000000 --- a/nwb_linkml/src/nwb_linkml/maps/hdmf.py +++ /dev/null @@ -1,24 +0,0 @@ -""" -Mapping functions for handling HDMF classes like DynamicTables -""" - -from typing import Any, List, Optional - -import h5py - - -def dereference_reference_vector(dset: h5py.Dataset, data: Optional[List[Any]]) -> List: - """ - Given a compound dataset with indices, counts, and object references, dereference to values - - Data is of the form - (idx_start, count, target) - """ - # assume all these references are to the same target - # and the index is in the 3rd position - if data is None: - data = dset[:] - - target = dset.parent.get(data[0][-1]) - res = [target[d[0] : d[0] + d[1]] for d in data] - return res diff --git a/nwb_linkml/tests/test_includes/test_hdmf.py b/nwb_linkml/tests/test_includes/test_hdmf.py index c5a164f..9654301 100644 --- a/nwb_linkml/tests/test_includes/test_hdmf.py +++ b/nwb_linkml/tests/test_includes/test_hdmf.py @@ -213,10 +213,47 @@ def test_aligned_dynamictable(intracellular_recordings_table): def test_dynamictable_mixin_indexing(): """ - This is just a placeholder test to say that indexing is tested above - with actual model objects in case i ever ctrl+f for this + Can index values from a dynamictable """ - pass + + class MyData(DynamicTableMixin): + col_1: hdmf.VectorData[NDArray[Shape["*"], int]] + col_2: hdmf.VectorData[NDArray[Shape["*"], int]] + col_3: hdmf.VectorData[NDArray[Shape["*"], int]] + + cols = { + "col_1": np.arange(10), + "col_2": np.arange(10), + "col_3": np.arange(10), + "col_4": np.arange(10), + "col_5": np.arange(10), + } + colnames = [c for c in cols] + inst = MyData(**cols) + + row = inst[0] + # successfully get a single row :) + assert row.shape == (1, 5) + assert row.columns.tolist() == colnames + + # slice a range of rows + rows = inst[0:3] + assert rows.shape == (3, 5) + + # get a single column + col = inst["col_1"] + assert all(col.value == np.arange(10)) + + # get a single cell + val = inst[5, "col_2"] + assert val == 5 + val = inst[5, 1] + assert val == 5 + + # get a slice of rows and columns + subsection = inst[0:3, 0:3] + assert subsection.shape == (3, 3) + assert subsection.columns.tolist() == colnames[0:3] def test_dynamictable_mixin_colnames(): diff --git a/nwb_linkml/tests/test_logging.py b/nwb_linkml/tests/test_logging.py new file mode 100644 index 0000000..4585ed1 --- /dev/null +++ b/nwb_linkml/tests/test_logging.py @@ -0,0 +1,35 @@ +from pathlib import Path + +from nwb_linkml.logging import init_logger + + +def test_init_logger(capsys, tmp_path): + """ + We should be able to + - log to file and stdout + - with separable levels + """ + + log_dir = Path(tmp_path) / "logs" + log_dir.mkdir() + log_file = log_dir / "nwb_linkml.test_logger.log" + logger = init_logger(name="test_logger", log_dir=log_dir, level="INFO", file_level="WARNING") + warn_msg = "Both loggers should show" + logger.warning(warn_msg) + + # can't test for presence of string because logger can split lines depending on size of console + # but there should be one WARNING in stdout + captured = capsys.readouterr() + assert "WARNING" in captured.out + + with open(log_file, "r") as lfile: + log_str = lfile.read() + assert "WARNING" in log_str + + info_msg = "Now only stdout should show" + logger.info(info_msg) + captured = capsys.readouterr() + assert "INFO" in captured.out + with open(log_file, "r") as lfile: + log_str = lfile.read() + assert "INFO" not in log_str