diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 46bccc3..2443567 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -35,7 +35,7 @@ jobs: python3 -m pip install .[test] - name: Run tests run: | - coverage run --omit=tests/*,*/_*.py -m unittest discover -v -p *_test.py . + coverage run --omit=tests/*,*/_*.py -m pytest coverage xml - name: Upload to codecov uses: codecov/codecov-action@v3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 5aebb46..61b5e81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,26 @@ All notable changes to this project will be documented in this file. + + +## [1.2.3] - 2024-07-26 + +### Features + +- (**mid**) Add missing `binary` constructor to `Midline` model. Now all models have a `binary` and `trinary` constructor. + +### Styling + +- Add rules to [ruff]. + +### Testing + +- Make suite testable with [pytest]. + +### Ci + +- Switch to [pytest] for testing. + ## [1.2.2] - 2024-06-25 @@ -23,11 +43,11 @@ All notable changes to this project will be documented in this file. ### Styling -- Use ruff to fix lint and format code. +- Use [ruff] to fix lint and format code. ### Build -- Remove upper cap in deps. +- Remove upper cap in dependencies because of [this](https://iscinumpy.dev/post/bound-version-constraints/). ### Change @@ -793,3 +813,6 @@ Almost the entire API has changed. I'd therefore recommend to have a look at the [#41]: https://github.com/rmnldwg/lymph/issues/41 [#40]: https://github.com/rmnldwg/lymph/issues/40 [#38]: https://github.com/rmnldwg/lymph/issues/38 + +[ruff]: https://astral.sh/ruff +[pytest]: https://docs.pytest.org/en/stable/ diff --git a/lymph/models/midline.py b/lymph/models/midline.py index e43414d..fef2b1d 100644 --- a/lymph/models/midline.py +++ b/lymph/models/midline.py @@ -105,7 +105,7 @@ def __init__( if is_symmetric["tumor_spread"]: raise ValueError( "If you want the tumor spread to be symmetric, consider using the " - "Bilateral class." + "Bilateral class.", ) self.is_symmetric = is_symmetric @@ -124,7 +124,7 @@ def __init__( if self.use_midext_evo and use_central: raise ValueError( "Evolution to central tumor not yet implemented. Choose to use either " - "the central model or the midline extension evolution." + "the central model or the midline extension evolution.", # Actually, this shouldn't be too hard, but we still need to think # about it for a bit. ) @@ -168,6 +168,13 @@ def __init__( is_modality_leaf=False, ) + @classmethod + def binary(cls, *args, **kwargs) -> Midline: + """Create a binary model.""" + uni_kwargs = kwargs.pop("uni_kwargs", {}) + uni_kwargs["allowed_states"] = [0, 1] + return cls(*args, uni_kwargs=uni_kwargs, **kwargs) + @classmethod def trinary(cls, *args, **kwargs) -> Midline: """Create a trinary model.""" @@ -242,7 +249,7 @@ def unknown(self) -> models.Bilateral: if self.marginalize_unknown: return self._unknown raise AttributeError( - "This instance does not marginalize over unknown midline extension." + "This instance does not marginalize over unknown midline extension.", ) def get_tumor_spread_params( @@ -262,15 +269,15 @@ def get_tumor_spread_params( if self.use_mixing: params["contra"] = self.noext.contra.get_tumor_spread_params( - as_flat=as_flat + as_flat=as_flat, ) params["mixing"] = self.mixing_param else: params["noext"] = { - "contra": self.noext.contra.get_tumor_spread_params(as_flat=as_flat) + "contra": self.noext.contra.get_tumor_spread_params(as_flat=as_flat), } params["ext"] = { - "contra": self.ext.contra.get_tumor_spread_params(as_flat=as_flat) + "contra": self.ext.contra.get_tumor_spread_params(as_flat=as_flat), } if as_flat or not as_dict: @@ -295,7 +302,7 @@ def get_lnl_spread_params( if ext_lnl_params != noext_lnl_params: raise ValueError( "LNL spread params not synched between ext and noext models. " - "Returning the ext params." + "Returning the ext params.", ) if self.use_central: @@ -303,7 +310,7 @@ def get_lnl_spread_params( if central_lnl_params != ext_lnl_params: warnings.warn( "LNL spread params not synched between central and ext models. " - "Returning the ext params." + "Returning the ext params.", ) if as_flat or not as_dict: @@ -412,7 +419,8 @@ def set_tumor_spread_params( noext_contra_kwargs = global_kwargs.copy() noext_contra_kwargs.update(kwargs.get("noext", {}).get("contra", {})) args = self.noext.contra.set_tumor_spread_params( - *args, **noext_contra_kwargs + *args, + **noext_contra_kwargs, ) ext_contra_kwargs = global_kwargs.copy() @@ -521,7 +529,7 @@ def load_patient_data( elif is_unknown.sum() > 0: warnings.warn( f"Discarding {is_unknown.sum()} patients where midline extension " - "is unknown." + "is unknown.", ) def midext_evo(self) -> np.ndarray: @@ -638,7 +646,9 @@ def obs_dist( """ if given_state_dist is None: given_state_dist = self.state_dist( - t_stage=t_stage, mode=mode, central=central + t_stage=t_stage, + mode=mode, + central=central, ) if given_state_dist.ndim == 2: @@ -653,7 +663,9 @@ def obs_dist( return np.stack(obs_dist) def _hmm_likelihood( - self, log: bool = True, for_t_stage: str | None = None + self, + log: bool = True, + for_t_stage: str | None = None, ) -> float: """Compute the likelihood of the stored data under the hidden Markov model.""" llh = 0.0 if log else 1.0 @@ -771,7 +783,9 @@ def posterior_state_dist( if given_state_dist is None: utils.safe_set_params(self, given_params) given_state_dist = self.state_dist( - t_stage=t_stage, mode=mode, central=central + t_stage=t_stage, + mode=mode, + central=central, ) if given_state_dist.ndim == 2: @@ -817,7 +831,9 @@ def marginalize( if given_state_dist is None: given_state_dist = self.state_dist( - t_stage=t_stage, mode=mode, central=central + t_stage=t_stage, + mode=mode, + central=central, ) if given_state_dist.ndim == 2: @@ -907,7 +923,7 @@ def draw_patients( if self.use_central: raise NotImplementedError( - "Drawing patients from the central model not yet supported." + "Drawing patients from the central model not yet supported.", ) drawn_t_stages = rng.choice( @@ -920,13 +936,16 @@ def draw_patients( [ distributions[t_stage].draw_diag_times(rng=rng) for t_stage in drawn_t_stages - ] + ], ) if self.use_midext_evo: midext_evo = self.midext_evo() drawn_midexts = np.array( - [rng.choice(a=[False, True], p=midext_evo[t]) for t in drawn_diag_times] + [ + rng.choice(a=[False, True], p=midext_evo[t]) + for t in drawn_diag_times + ], ) else: drawn_midexts = rng.choice( @@ -956,7 +975,8 @@ def draw_patients( seed=seed, ) drawn_case_diags = np.concatenate( - [drawn_ipsi_diags, drawn_contra_diags], axis=1 + [drawn_ipsi_diags, drawn_contra_diags], + axis=1, ) drawn_diags[drawn_midexts == (case == "ext")] = drawn_case_diags diff --git a/pyproject.toml b/pyproject.toml index f151b69..32a5bc5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,21 +1,15 @@ [build-system] -requires = [ - "setuptools >= 61.0.0", - "setuptools_scm >= 7.0.0", - "wheel", -] +requires = ["setuptools >= 61.0.0", "setuptools_scm >= 7.0.0", "wheel"] build-backend = "setuptools.build_meta" [project] name = "lymph-model" description = "Package for statistical modelling of lymphatic metastatic spread." -authors = [ - {name = "Roman Ludwig", email = "roman.ludwig@usz.ch"} -] +authors = [{ name = "Roman Ludwig", email = "roman.ludwig@usz.ch" }] readme = "README.rst" requires-python = ">=3.10" keywords = ["cancer", "metastasis", "lymphatic progression", "model"] -license = {text = "MIT"} +license = { text = "MIT" } classifiers = [ "Development Status :: 3 - Alpha", "License :: OSI Approved :: MIT License", @@ -26,24 +20,12 @@ classifiers = [ "Operating System :: OS Independent", "Topic :: Scientific/Engineering", ] -dependencies = [ - "numpy", - "pandas", - "cachetools", -] +dependencies = ["numpy", "pandas", "cachetools"] dynamic = ["version"] [project.optional-dependencies] -test = [ - "scipy", - "coverage", - "emcee", -] -dev = [ - "pre-commit", - "pylint", - "git-cliff", -] +test = ["pytest", "scipy", "coverage", "emcee"] +dev = ["pre-commit"] docs = [ "sphinx", "sphinx-book-theme", @@ -68,7 +50,12 @@ packages = ["lymph"] include-package-data = true [tool.setuptools.dynamic] -version = {attr = "lymph._version.version"} +version = { attr = "lymph._version.version" } + + +[tool.pytest.ini_options] +testpaths = ["tests"] +filterwarnings = ["ignore::pandas.errors.PerformanceWarning"] [tool.isort] @@ -87,7 +74,24 @@ all = true exclude = ["tests", "docs"] [tool.ruff.lint] -select = ["E", "F", "W", "B", "C", "R", "U", "D", "I", "S", "T", "A", "N", "NPY201"] +select = [ + "E", + "F", + "W", + "B", + "C", + "R", + "U", + "D", + "I", + "S", + "T", + "A", + "N", + "COM", + "FURB", + "NPY201", +] ignore = ["B028"] @@ -141,20 +145,20 @@ filter_unconventional = true split_commits = false # regex for preprocessing the commit messages commit_preprocessors = [ - # { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](https://github.com/orhun/git-cliff/issues/${2}))"}, # replace issue numbers + # { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](https://github.com/orhun/git-cliff/issues/${2}))"}, # replace issue numbers ] # regex for parsing and grouping commits commit_parsers = [ - { message = "^feat", group = "Features" }, - { message = "^fix", group = "Bug Fixes" }, - { message = "^docs", group = "Documentation" }, - { message = "^perf", group = "Performance" }, - { message = "^refactor", group = "Refactor" }, - { message = "^style", group = "Styling" }, - { message = "^test", group = "Testing" }, - { message = "^chore\\(release\\): prepare for", skip = true }, - { message = "^chore", group = "Miscellaneous Tasks" }, - { body = ".*security", group = "Security" }, + { message = "^feat", group = "Features" }, + { message = "^fix", group = "Bug Fixes" }, + { message = "^docs", group = "Documentation" }, + { message = "^perf", group = "Performance" }, + { message = "^refactor", group = "Refactor" }, + { message = "^style", group = "Styling" }, + { message = "^test", group = "Testing" }, + { message = "^chore\\(release\\): prepare for", skip = true }, + { message = "^chore", group = "Miscellaneous Tasks" }, + { body = ".*security", group = "Security" }, ] # protect breaking changes from being skipped due to matching a skipping commit_parser protect_breaking_commits = false diff --git a/tests/bayesian_unilateral_test.py b/tests/bayesian_unilateral_test.py index a7dde2f..b30ac10 100644 --- a/tests/bayesian_unilateral_test.py +++ b/tests/bayesian_unilateral_test.py @@ -1,4 +1,5 @@ """Test the Bayesian Unilateral Model.""" +import unittest import numpy as np @@ -7,7 +8,7 @@ class BayesianUnilateralModelTestCase( fixtures.BinaryUnilateralModelMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Test the Bayesian Unilateral Model.""" diff --git a/tests/binary_bilateral_test.py b/tests/binary_bilateral_test.py index 95edde3..31f8551 100644 --- a/tests/binary_bilateral_test.py +++ b/tests/binary_bilateral_test.py @@ -1,4 +1,5 @@ """Test the bilateral model.""" +import unittest import numpy as np @@ -8,7 +9,7 @@ from . import fixtures -class BilateralInitTest(fixtures.BilateralModelMixin, fixtures.IgnoreWarningsTestCase): +class BilateralInitTest(fixtures.BilateralModelMixin, unittest.TestCase): """Test the delegation of attrs from the unilateral class to the bilateral one.""" def setUp(self): @@ -83,7 +84,7 @@ def test_asymmetric_model(self): class ModalityDelegationTestCase( fixtures.BilateralModelMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Make sure the modality is delegated from the ipsi side correctly.""" @@ -156,7 +157,7 @@ def test_diag_time_dists_delegation(self): class NoSymmetryParamsTestCase( fixtures.BilateralModelMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Test the parameter assignment when the model is not symmetric""" @@ -241,7 +242,7 @@ def test_set_params_as_dict(self): class SymmetryParamsTestCase( fixtures.BilateralModelMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Test the parameter assignment when the model is symmetric.""" @@ -285,7 +286,7 @@ def test_set_params_as_dict(self): self.assertEqual(params_to_set, self.model.ipsi.get_params()) -class LikelihoodTestCase(fixtures.BilateralModelMixin, fixtures.IgnoreWarningsTestCase): +class LikelihoodTestCase(fixtures.BilateralModelMixin, unittest.TestCase): """Check that the (log-)likelihood is computed correctly.""" def setUp(self): @@ -300,7 +301,7 @@ def test_compute_likelihood_twice(self): self.assertEqual(first_llh, second_llh) -class RiskTestCase(fixtures.BilateralModelMixin, fixtures.IgnoreWarningsTestCase): +class RiskTestCase(fixtures.BilateralModelMixin, unittest.TestCase): """Check that the risk is computed correctly.""" def setUp(self): @@ -358,7 +359,7 @@ def test_risk(self): class DataGenerationTestCase( fixtures.BilateralModelMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Check the binary model's data generation method.""" diff --git a/tests/binary_midline_test.py b/tests/binary_midline_test.py index 30ff19a..215b969 100644 --- a/tests/binary_midline_test.py +++ b/tests/binary_midline_test.py @@ -1,4 +1,5 @@ """Test the midline model for the binary case.""" +import unittest import numpy as np import pandas as pd @@ -10,7 +11,7 @@ class MidlineSetParamsTestCase( fixtures.MidlineFixtureMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Check that the complex parameter assignment works correctly.""" @@ -62,7 +63,7 @@ def test_get_set_params_order(self) -> None: class MidlineLikelihoodTestCase( fixtures.MidlineFixtureMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Check that the likelihood function works correctly.""" @@ -92,7 +93,7 @@ def test_likelihood(self) -> None: class MidlineRiskTestCase( fixtures.MidlineFixtureMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Check that the risk method works correctly.""" @@ -155,7 +156,7 @@ def test_risk_given_state_dist(self) -> None: self.assertTrue(np.allclose(risk_from_state_dist, risk_direct)) -class MidlineDrawPatientsTestCase(fixtures.IgnoreWarningsTestCase): +class MidlineDrawPatientsTestCase(unittest.TestCase): """Check the data generation.""" def setUp(self) -> None: diff --git a/tests/binary_unilateral_test.py b/tests/binary_unilateral_test.py index 601114a..10274fa 100644 --- a/tests/binary_unilateral_test.py +++ b/tests/binary_unilateral_test.py @@ -1,4 +1,5 @@ """Test the binary unilateral system.""" +import unittest import warnings @@ -13,7 +14,7 @@ class InitTestCase( fixtures.BinaryUnilateralModelMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Test the initialization of a binary model.""" @@ -94,7 +95,7 @@ def test_tumor_to_lnl_edges(self): class ParameterAssignmentTestCase( fixtures.BinaryUnilateralModelMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Test the assignment of parameters in a binary model.""" @@ -137,7 +138,7 @@ def test_transition_matrix_deletion(self): class TransitionMatrixTestCase( fixtures.BinaryUnilateralModelMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Test the generation of the transition matrix in a binary model.""" @@ -183,7 +184,7 @@ def test_is_recusively_upper_triangular(self) -> None: class ObservationMatrixTestCase( fixtures.BinaryUnilateralModelMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Test the generation of the observation matrix in a binary model.""" @@ -207,7 +208,7 @@ def test_is_probabilistic(self): class PatientDataTestCase( fixtures.BinaryUnilateralModelMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Test loading the patient data.""" @@ -313,7 +314,7 @@ def test_modality_replacement(self) -> None: class LikelihoodTestCase( fixtures.BinaryUnilateralModelMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Test the likelihood of a model.""" @@ -351,7 +352,7 @@ def test_compute_likelihood_twice(self): class RiskTestCase( fixtures.BinaryUnilateralModelMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Test anything related to the risk computation.""" @@ -414,7 +415,7 @@ def test_risk(self): class DataGenerationTestCase( fixtures.BinaryUnilateralModelMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Check the data generation utilities.""" diff --git a/tests/distribution_test.py b/tests/distribution_test.py index e3a1b5f..6c4d588 100644 --- a/tests/distribution_test.py +++ b/tests/distribution_test.py @@ -1,4 +1,5 @@ """Check functionality of the distribution over diagnosis times.""" +import unittest import warnings @@ -7,8 +8,6 @@ from lymph.diagnosis_times import Distribution -from . import fixtures - class FixtureMixin: """Mixin that provides fixtures for the tests.""" @@ -35,7 +34,7 @@ def setUp(self): self.func_arg = lambda support, p=0.5: self.binom_pmf(support, self.max_time, p) -class DistributionTestCase(FixtureMixin, fixtures.IgnoreWarningsTestCase): +class DistributionTestCase(FixtureMixin, unittest.TestCase): """Test the distribution dictionary.""" def test_frozen_distribution_without_max_time(self): diff --git a/tests/edge_test.py b/tests/edge_test.py index c595afb..2350931 100644 --- a/tests/edge_test.py +++ b/tests/edge_test.py @@ -1,13 +1,12 @@ """Unit tests for the Edge class.""" +import unittest import numpy as np from lymph import graph -from . import fixtures - -class BinaryEdgeTestCase(fixtures.IgnoreWarningsTestCase): +class BinaryEdgeTestCase(unittest.TestCase): """Tests for the Edge class.""" def setUp(self) -> None: @@ -50,7 +49,7 @@ def test_transition_tensor_row_sums(self) -> None: self.assertTrue(np.allclose(row_sum, 1.0)) -class TrinaryEdgeTestCase(fixtures.IgnoreWarningsTestCase): +class TrinaryEdgeTestCase(unittest.TestCase): """Tests for the Edge class in case the parent and child node are trinary.""" def setUp(self) -> None: diff --git a/tests/emcee_intergration_test.py b/tests/emcee_intergration_test.py index 364a1fc..994c359 100644 --- a/tests/emcee_intergration_test.py +++ b/tests/emcee_intergration_test.py @@ -1,4 +1,5 @@ """Make sure the models work with the emcee package.""" +import unittest import emcee import numpy as np @@ -8,7 +9,7 @@ class UnilateralEmceeTestCase( fixtures.BinaryUnilateralModelMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Test the emcee package with the Unilateral model.""" diff --git a/tests/fixtures.py b/tests/fixtures.py index 19120a4..1b450dd 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -1,7 +1,6 @@ """Fxitures for tests.""" import logging -import unittest import warnings from collections.abc import Callable from pathlib import Path @@ -14,7 +13,7 @@ from lymph import diagnosis_times from lymph.modalities import Clinical, Modality, Pathological from lymph.models import Bilateral, Midline, Unilateral -from lymph.types import DataWarning, PatternType +from lymph.types import PatternType MODALITIES = { "CT": Clinical(spec=0.81, sens=0.86), @@ -23,16 +22,6 @@ RNG = np.random.default_rng(42) -class IgnoreWarningsTestCase(unittest.TestCase): - """Test case that ignores warnings.""" - - def setUp(self) -> None: - """Ignore warnings.""" - warnings.simplefilter("ignore", category=pd.errors.PerformanceWarning) - warnings.simplefilter("ignore", category=DataWarning) - super().setUp() - - def get_graph(size: str = "large") -> dict[tuple[str, str], list[str]]: """Return either a ``"small"``, a ``"medium"`` or a ``"large"`` graph.""" if size == "small": diff --git a/tests/graph_representation_test.py b/tests/graph_representation_test.py index b50c6b5..f9195f0 100644 --- a/tests/graph_representation_test.py +++ b/tests/graph_representation_test.py @@ -1,13 +1,12 @@ """Test the graph representation class of the package.""" +import unittest import numpy as np from lymph import graph -from . import fixtures - -class ConstructBinaryGraphRepresentationTestCase(fixtures.IgnoreWarningsTestCase): +class ConstructBinaryGraphRepresentationTestCase(unittest.TestCase): """Test suite for the graph representation class.""" def setUp(self) -> None: diff --git a/tests/integration_test.py b/tests/integration_test.py index bad6a2a..0f15d2b 100644 --- a/tests/integration_test.py +++ b/tests/integration_test.py @@ -3,6 +3,7 @@ This is directly taken from the quickstart guide. Aimed at checking the computed value of the likelihood function. """ +import unittest import numpy as np import scipy as sp @@ -19,7 +20,7 @@ def late_binomial(support: np.ndarray, p: float = 0.5) -> np.ndarray: class IntegrationTestCase( fixtures.BinaryUnilateralModelMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Run a stripped down version of the quickstart guide.""" diff --git a/tests/node_test.py b/tests/node_test.py index 1631a4c..d2b8a71 100644 --- a/tests/node_test.py +++ b/tests/node_test.py @@ -1,11 +1,10 @@ """Unit tests for the Node classes.""" +import unittest from lymph import graph -from . import fixtures - -class BinaryLymphNodeLevelTestCase(fixtures.IgnoreWarningsTestCase): +class BinaryLymphNodeLevelTestCase(unittest.TestCase): """Test case for a binary lymph node level.""" def setUp(self) -> None: diff --git a/tests/trinary_midline_test.py b/tests/trinary_midline_test.py index d3ef4c5..f04104f 100644 --- a/tests/trinary_midline_test.py +++ b/tests/trinary_midline_test.py @@ -1,5 +1,5 @@ """Test the midline model for the binary case.""" - +import unittest from typing import Literal import numpy as np @@ -9,7 +9,7 @@ from . import fixtures -class MidlineSetParamsTestCase(fixtures.IgnoreWarningsTestCase): +class MidlineSetParamsTestCase(unittest.TestCase): """Check that the complex parameter assignment works correctly.""" def setUp( diff --git a/tests/trinary_unilateral_test.py b/tests/trinary_unilateral_test.py index 970fcf0..31ab773 100644 --- a/tests/trinary_unilateral_test.py +++ b/tests/trinary_unilateral_test.py @@ -1,4 +1,5 @@ """Test the trinary unilateral system.""" +import unittest import numpy as np import pandas as pd @@ -11,7 +12,7 @@ class TrinaryInitTestCase( fixtures.TrinaryFixtureMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Testing the basic initialization of a trinary model.""" @@ -32,7 +33,7 @@ def test_lnls(self): class TrinaryTransitionMatrixTestCase( fixtures.TrinaryFixtureMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Test the transition matrix of a trinary model.""" @@ -72,7 +73,7 @@ def test_transition_matrix(self) -> None: class TrinaryObservationMatrixTestCase( fixtures.TrinaryFixtureMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Test the observation matrix of a trinary model.""" @@ -95,7 +96,7 @@ def test_observation_matrix(self) -> None: class TrinaryDiagnosisMatricesTestCase( fixtures.TrinaryFixtureMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Test the diagnosis matrix of a trinary model.""" @@ -121,7 +122,7 @@ def test_diagnosis_matrices_shape(self) -> None: class TrinaryParamAssignmentTestCase( fixtures.TrinaryFixtureMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Test the assignment of parameters in a trinary model.""" @@ -147,7 +148,7 @@ def test_edge_params(self): class TrinaryLikelihoodTestCase( fixtures.TrinaryFixtureMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Test the likelihood of a trinary model.""" @@ -179,7 +180,7 @@ def test_likelihood_invalid_params_isinf(self): class TrinaryRiskTestCase( fixtures.TrinaryFixtureMixin, - fixtures.IgnoreWarningsTestCase, + unittest.TestCase, ): """Test the risk of a trinary model."""