Skip to content

Commit 86fee26

Browse files
authored
Enhance test coverage and improve error handling -> 1.1.1 (#5)
1 parent e791cea commit 86fee26

7 files changed

Lines changed: 69 additions & 46 deletions

File tree

.github/workflows/ci.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,12 @@ jobs:
2929
run: uv sync --dev
3030

3131
- name: Run tests with coverage
32-
run: uv run pytest -v --cov=src --cov-report=term --cov-report=xml
32+
run: uv run pytest -v --cov=src --cov-branch --cov-report=term --cov-report=xml
33+
34+
- name: Upload coverage reports to Codecov
35+
uses: codecov/codecov-action@v5
36+
with:
37+
token: ${{ secrets.CODECOV_TOKEN }}
3338

3439
lint:
3540
runs-on: ubuntu-latest

README.md

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
![PyPI Version](https://img.shields.io/pypi/v/casregnum)
44
![CI](https://github.com/molshape/CASRegistryNumbers/actions/workflows/ci.yml/badge.svg)
5+
[![codecov](https://codecov.io/github/molshape/CASRegistryNumbers/graph/badge.svg?token=5HZN6RX2XA)](https://codecov.io/github/molshape/CASRegistryNumbers) \
56
![Python Versions](https://img.shields.io/pypi/pyversions/casregnum)
67
![License](https://img.shields.io/github/license/molshape/casregnum) \
78
![GitHub stars](https://img.shields.io/github/stars/molshape/casregnum)
@@ -10,7 +11,7 @@
1011
Python class to manage, check and sort CAS Registry Numbers® (CAS RN®).
1112

1213
<details>
13-
<summary>Table of Content</summary>
14+
<summary>Table of Contents</summary>
1415

1516
1. [Description](#description)
1617
2. [How to install and uninstall?](#how-to-install-and-uninstall)
@@ -23,17 +24,25 @@ Python class to manage, check and sort CAS Registry Numbers&reg; (CAS RN&reg;).
2324
**casregnum** is a Python class to manage, check, and sort CAS Registry Numbers&reg; (CAS RN&reg;) by the [Chemical Abstracts Service](https://www.cas.org/). Check their official [FAQ website](https://www.cas.org/support/documentation/chemical-substances/faqs) for more information on CAS numbers.
2425

2526

26-
## How to install and uninstall?
27+
## How to install and uninstall
2728
**casregnum** can be installed from the [Python Package Index (PyPI)](https://pypi.org/) repository by calling
2829

29-
pip install casregnum
30+
pip install casregnum
31+
32+
or
33+
34+
uv add casregnum
3035

3136
In order to uninstall **casregnum** from your local environment use
3237

33-
pip uninstall casregnum
38+
pip uninstall casregnum
39+
40+
or
41+
42+
uv remove casregnum
3443

3544

36-
## How to use?
45+
## How to use
3746
**casregnum** provides the `CAS` class for creating a CAS Registry Number&reg; instance:
3847

3948
```Python
@@ -81,18 +90,15 @@ for i, isomer in enumerate(sorted(octanes), start=1):
8190
print()
8291
```
8392

84-
will generate the following output:
85-
86-
```
87-
str: 58-08-2
88-
int: 58082
89-
check digit: 2
90-
58-08-2 == 58-08-2: True
91-
58-08-2 > 58-08-2: False
92-
79-33-4 > 10326-41-7: False
93-
79-33-4 < 10326-41-7: True
94-
111-65-9, 540-84-1, 560-21-4, 563-16-6, 564-02-3, 565-75-3,
95-
583-48-2, 584-94-1, 589-43-5, 589-53-7, 589-81-1, 590-73-8,
96-
592-13-2, 592-27-8, 594-82-1, 609-26-7, 619-99-8, 1067-08-9,
97-
```
98-
93+
This will generate the following output:
94+
95+
str: 58-08-2
96+
int: 58082
97+
check digit: 2
98+
58-08-2 == 58-08-2: True
99+
58-08-2 > 58-08-2: False
100+
79-33-4 > 10326-41-7: False
101+
79-33-4 < 10326-41-7: True
102+
111-65-9, 540-84-1, 560-21-4, 563-16-6, 564-02-3, 565-75-3,
103+
583-48-2, 584-94-1, 589-43-5, 589-53-7, 589-81-1, 590-73-8,
104+
592-13-2, 592-27-8, 594-82-1, 609-26-7, 619-99-8, 1067-08-9,

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "casregnum"
3-
version = "1.1.0"
3+
version = "1.1.1"
44
description = "Python class to manage, check and sort CAS Registry Numbers® (CAS RN®)"
55
readme = "README.md"
66
authors = [

src/casregnum/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
try:
55
from importlib.metadata import version
66
__version__ = version("casregnum")
7-
except ImportError:
8-
__version__ = "unknown"
7+
except ImportError: # pragma: no cover
8+
__version__ = "unknown" # pragma: no cover

src/casregnum/casregnum.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import re
2-
31
"""
42
Class for CAS Registry Numbers® (CAS RN®)
53
allows to manage, check and sort CAS Registry Numbers®
@@ -8,6 +6,10 @@
86
and the calculation method to determine the check digit
97
"""
108

9+
from __future__ import annotations
10+
11+
import re
12+
1113

1214
class CAS:
1315
"""
@@ -53,15 +55,15 @@ def __format__(self, format_spec) -> str:
5355
return f"{self.cas_string:{format_spec}}"
5456

5557
# checks if two CAS Registry Numbers are equal
56-
def __eq__(self, other: object) -> bool:
58+
def __eq__(self, other: CAS) -> bool:
5759
if not isinstance(other, CAS):
58-
return False
60+
raise TypeError("Comparisons can only be made between CAS objects.")
5961
return self.cas_integer == other.cas_integer
6062

6163
# checks if self.cas_integer < other.cas_integer
62-
def __lt__(self, other: object) -> bool:
64+
def __lt__(self, other: CAS) -> bool:
6365
if not isinstance(other, CAS):
64-
return NotImplemented
66+
raise TypeError("Comparisons can only be made between CAS objects.")
6567
return self.cas_integer < other.cas_integer
6668

6769
# Returns CAS Registry Number
@@ -70,7 +72,7 @@ def cas_string(self) -> str:
7072
"""
7173
Returns the CAS Registry Number as a formatted string (e.g. "58-08-2").
7274
"""
73-
return self.__cas_string
75+
return self._cas_string
7476

7577
# Sets CAS Registry Number
7678
# if the passed input value is a string, parse the string according to _____00-00-0
@@ -79,23 +81,23 @@ def cas_string(self) -> str:
7981
def cas_string(self, cas_rn: str) -> None:
8082
# convert (formatted) CAS string into integer
8183
if regex_cas := re.match(r"^(\d{2,7})\-(\d{2})-(\d{1})$", cas_rn):
82-
self.cas_integer = self.__cas_integer = int(
84+
self.cas_integer = self._cas_integer = int(
8385
regex_cas.group(1) + regex_cas.group(2) + regex_cas.group(3)
8486
)
8587
# cas_rn is not following the notation rule for CAS numbers => ValueError
8688
else:
8789
raise ValueError(
8890
f"Invalid CAS number format for '{cas_rn}' (must follow the notation _____00-00-0)"
8991
)
90-
self.__cas_string = cas_rn
92+
self._cas_string = cas_rn
9193

9294
# Returns CAS Registry Number as an integer (without the hyphens)
9395
@property
9496
def cas_integer(self) -> int:
9597
"""
9698
Returns the CAS Registry Number as an integer (e.g. 58082).
9799
"""
98-
return self.__cas_integer
100+
return self._cas_integer
99101

100102
@cas_integer.setter
101103
def cas_integer(self, cas_rn: int) -> None:
@@ -106,15 +108,15 @@ def cas_integer(self, cas_rn: int) -> None:
106108
raise ValueError(
107109
f"Invalid CAS number '{cas_rn}' (must be an integer between 10004 and 9999999995)"
108110
)
109-
self.__cas_integer = cas_rn
111+
self._cas_integer = cas_rn
110112

111113
# Returns check digit of the CAS Registry Number
112114
@property
113115
def check_digit(self) -> int:
114116
"""
115117
Returns the check digit of the CAS Registry Number (e.g. 2 for "58-08-2").
116118
"""
117-
return self.__check_digit
119+
return self._check_digit
118120

119121
# Sets the CAS Registry Number check digit
120122
@check_digit.setter
@@ -134,4 +136,4 @@ def check_digit(self, digit_to_test: int) -> None:
134136
f"Invalid CAS number '{self.cas_string}' "
135137
f"(found check digit '{digit_to_test}', but expected '{check_sum % 10}')"
136138
)
137-
self.__check_digit = int(digit_to_test)
139+
self._check_digit = int(digit_to_test)

test/test_functionality.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,21 +78,31 @@ def test_for_sorting(octanes, octanes_sorted):
7878
# Tests for error handling
7979

8080

81-
@pytest.mark.xfail(raises=TypeError)
81+
def test_cas_equal_invalid(caffeine):
82+
with pytest.raises(TypeError):
83+
assert caffeine == "theine"
84+
85+
86+
def test_cas_lesser_than_invalid(l_lacticacid):
87+
with pytest.raises(TypeError):
88+
assert l_lacticacid < "D-lactic acid"
89+
90+
8291
def test_cas_invalid_input():
83-
CAS(6417.5)
92+
with pytest.raises(TypeError):
93+
CAS(6417.5)
8494

8595

86-
@pytest.mark.xfail(raises=ValueError)
8796
def test_cas_format_unreadable():
88-
CAS("64 - 17 - 5")
97+
with pytest.raises(ValueError):
98+
CAS("64 - 17 - 5")
8999

90100

91-
@pytest.mark.xfail(raises=ValueError)
92101
def test_cas_range_error():
93-
CAS(100)
102+
with pytest.raises(ValueError):
103+
CAS(100)
94104

95105

96-
@pytest.mark.xfail(raises=ValueError)
97106
def test_cas_check_digit_error():
98-
CAS("64-17-6")
107+
with pytest.raises(ValueError):
108+
CAS("64-17-6")

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)