Skip to content

Commit

Permalink
[MNT] Increase test coverage (#216)
Browse files Browse the repository at this point in the history
* refactor fixtures

* update tests

* add test for electronegativity functions

* 💄

* add pytest-cov
  • Loading branch information
lmmentel authored Dec 29, 2024
1 parent 1329636 commit cbda8e7
Show file tree
Hide file tree
Showing 5 changed files with 228 additions and 24 deletions.
12 changes: 6 additions & 6 deletions mendeleev/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ def protons(self) -> int:
@hybrid_property
def mass(self) -> float:
"""
Return the `atomic_weight` if defined or mass number otherwise.
Alias for ``atomic_weight``.
"""
return self.atomic_weight

Expand Down Expand Up @@ -414,7 +414,7 @@ def mass_str(self) -> str:
@hybrid_property
def covalent_radius(self) -> float:
"""
Return the default covalent radius which is covalent_radius_pyykko
Return the default covalent radius i.e. ``covalent_radius_pyykko``
"""
return self.covalent_radius_pyykko

Expand All @@ -424,8 +424,8 @@ def hardness(self, charge: int = 0) -> Union[float, None]:
Return the absolute hardness, calculated as
Args:
charge: Charge of the cation for which the hardness will be calculated.
Defaultf to 0.
charge: Charge of the cation for which the hardness will be calculated.
Default is 0.
.. math::
Expand Down Expand Up @@ -457,12 +457,12 @@ def hardness(self, charge: int = 0) -> Union[float, None]:
raise ValueError(f"Charge has to be a non-negative integer, got: {charge}")

@hybrid_method
def softness(self, charge: int = 0) -> Union[float, None]:
def softness(self, charge: int = 0) -> float | None:
r"""
Return the absolute softness.
Args:
charge: Charge of the cation for which the hardness will be calculated
charge: Charge of the cation for which the hardness will be calculated
.. math::
Expand Down
107 changes: 106 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ sphinx-copybutton = "^0.3.1"
sphinx-material = "^0.0.32"
sphinxcontrib-bibtex = "^2.1.4"
pytest-xdist = "^3.6.1"
coverage = "^7.6.10"
pytest-cov = "^6.0.0"

[tool.poetry.group.vis]
optional = true
Expand Down
61 changes: 60 additions & 1 deletion tests/test_electronegativity.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import pytest

from mendeleev.models import Element
from mendeleev.electronegativity import mulliken
from mendeleev.electronegativity import (
n_effective,
allred_rochow,
cottrell_sutton,
gordy,
li_xue,
martynov_batsanov,
mulliken,
nagle,
sanderson,
generic,
)


def test_scales_exception():
Expand All @@ -15,3 +26,51 @@ def test_mulliken():
assert mulliken(None, 1.0) is None
assert mulliken(2.0, None) == pytest.approx(1.0)
assert mulliken(2.0, 1.0) == pytest.approx(1.5)


def test_n_effective():
assert n_effective(1, "slater") == pytest.approx(1.0)
assert n_effective(3, "zhang") == pytest.approx(2.89)
with pytest.raises(ValueError):
n_effective(2, "invalid")


def test_allred_rochow():
assert allred_rochow(4.0, 1.0) == pytest.approx(4.0)
assert allred_rochow(9.0, 3.0) == pytest.approx(1.0)


def test_cottrell_sutton():
assert cottrell_sutton(4.0, 1.0) == pytest.approx(2.0)
assert cottrell_sutton(9.0, 4.0) == pytest.approx(1.5)


def test_gordy():
assert gordy(6.0, 2.0) == pytest.approx(3.0)
assert gordy(8.0, 4.0) == pytest.approx(2.0)


def test_li_xue():
assert li_xue(13.6, 1.0, 1) == pytest.approx(
n_effective(1, "zhang") * 100.0, rel=1e-1
)


def test_martynov_batsanov():
assert martynov_batsanov([13.6, 24.6]) == pytest.approx(4.370354676682432)
assert martynov_batsanov([10.0, 20.0, 30.0]) == pytest.approx(4.47213595499958)


def test_nagle():
assert nagle(2, 4.0) == pytest.approx(0.7937005259840998)
assert nagle(8, 64.0) == pytest.approx(0.5)


def test_sanderson():
assert sanderson(1.0, 2.0) == pytest.approx(8.0)
assert sanderson(2.0, 4.0) == pytest.approx(8.0)


def test_generic():
assert generic(4.0, 2.0, 2, 1) == pytest.approx(1.0)
assert generic(9.0, 3.0, 2, 0.5) == pytest.approx(1.0)
70 changes: 54 additions & 16 deletions tests/test_element.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import math
import pytest
from mendeleev import element, get_all_elements, get_attribute_for_all_elements
from mendeleev.db import get_session
Expand Down Expand Up @@ -47,30 +48,46 @@ def test_elements_get_by_name(name):
assert e.name == name


@pytest.mark.parametrize("symbol", SYMBOLS)
def test_elements_str(symbol):
e = element(symbol)
str(e)
@pytest.mark.parametrize("element_obj", ELEMENTS)
def test_elements_str(element_obj):
str(element_obj)


@pytest.mark.parametrize("symbol", SYMBOLS)
def test_elements_repr(symbol):
e = element(symbol)
repr(e)
@pytest.mark.parametrize("element_obj", ELEMENTS)
def test_elements_repr(element_obj):
repr(element_obj)


@pytest.mark.parametrize("symbol", SYMBOLS)
def test_isotopes_str(symbol):
e = element(symbol)
for i in e.isotopes:
@pytest.mark.parametrize("element_obj", ELEMENTS)
def test_isotopes_str(element_obj):
for i in element_obj.isotopes:
str(i)
repr(i)


@pytest.mark.parametrize("symbol", SYMBOLS)
def test_electrophilicity(symbol):
e = element(symbol)
e.electrophilicity()
@pytest.mark.parametrize("element_obj", ELEMENTS)
def test_electrophilicity(element_obj):
assert isinstance(element_obj.electrophilicity(), (float, type(None)))


@pytest.mark.parametrize("element_obj", ELEMENTS)
def test_hardness(element_obj):
assert isinstance(element_obj.hardness(), (float, type(None)))


@pytest.mark.parametrize("element_obj", ELEMENTS)
def test_hardness_charge_1(element_obj):
assert isinstance(element_obj.hardness(charge=1), (float, type(None)))


@pytest.mark.parametrize("element_obj", ELEMENTS)
def test_softness(element_obj):
assert isinstance(element_obj.softness(), (float, type(None)))


@pytest.mark.parametrize("element_obj", ELEMENTS)
def test_softness_charge_1(element_obj):
assert isinstance(element_obj.softness(charge=1), (float, type(None)))


@pytest.mark.parametrize("element_obj", ELEMENTS)
Expand All @@ -92,3 +109,24 @@ def test_melting_points_float_or_none(e):
@pytest.mark.parametrize("e", ELEMENTS)
def test_boiling_points_float_or_none(e):
assert isinstance(e.boiling_point, (float, type(None)))


@pytest.mark.parametrize("element_obj", ELEMENTS)
def test_specific_heat_hybrid_property(element_obj):
if (
element_obj.specific_heat is not None
and element_obj.specific_heat_capacity is not None
):
assert math.isclose(
element_obj.specific_heat, element_obj.specific_heat_capacity, rel_tol=1e-5
)


@pytest.mark.parametrize("element_obj", ELEMENTS)
def test_protons(element_obj):
assert element_obj.protons == element_obj.atomic_number


@pytest.mark.parametrize("element_obj", ELEMENTS)
def test_electrons(element_obj):
assert element_obj.electrons == element_obj.atomic_number

0 comments on commit cbda8e7

Please # to comment.