Skip to content

Commit ac46732

Browse files
authored
Merge pull request #218 from derek73/test/config-coverage-gaps
Add tests for uncovered config error/deletion paths
2 parents b62620a + 51d6a44 commit ac46732

1 file changed

Lines changed: 41 additions & 0 deletions

File tree

tests/test_constants.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import re
44
import timeit
55

6+
import pytest
7+
68
from nameparser import HumanName
79
from nameparser.config import Constants, RegexTupleManager, SetManager, TupleManager
810
from nameparser.config.regexes import EMPTY_REGEX
@@ -445,6 +447,45 @@ def test_replaced_manager_no_longer_invalidates_cache(self) -> None:
445447
self.assertIs(c.suffixes_prefixes_titles, primed)
446448
self.assertNotIn('ghost', c.suffixes_prefixes_titles)
447449

450+
def test_tuplemanager_delattr_removes_dict_entry(self) -> None:
451+
"""Deleting a non-dunder attribute must remove the dict entry.
452+
453+
TupleManager routes non-dunder attribute deletion to ``del self[attr]``
454+
(the mirror of its dot-notation __setattr__), so ``del tm.key`` and
455+
``del tm['key']`` are the same operation.
456+
"""
457+
c = Constants()
458+
c.nickname_delimiters['curly_braces'] = re.compile(r'\{(.*?)\}')
459+
self.assertIn('curly_braces', c.nickname_delimiters)
460+
del c.nickname_delimiters.curly_braces # type: ignore[attr-defined]
461+
self.assertNotIn('curly_braces', c.nickname_delimiters)
462+
463+
def test_assigning_non_setmanager_to_cached_union_member_raises(self) -> None:
464+
"""A cached-union attribute rejects a plain iterable, demanding a SetManager.
465+
466+
The four ``_CachedUnionMember`` attributes wire an on-change callback into
467+
the assigned manager; a bare list would silently break cache invalidation,
468+
so __set__ fails loud with a message telling the caller to wrap it.
469+
"""
470+
c = Constants()
471+
with pytest.raises(TypeError, match='SetManager'):
472+
c.titles = ['mr', 'ms'] # type: ignore[assignment]
473+
474+
def test_setstate_raises_on_missing_descriptor_field(self) -> None:
475+
"""Unpickling a state blob missing a cached-union collection must fail loudly.
476+
477+
__setstate__ verifies every ``_CachedUnionMember``-backed attribute was
478+
restored; a missing one would otherwise surface much later as an
479+
AttributeError on the private mangled name (e.g. ``_titles``), which is
480+
far harder to diagnose than a named ValueError here.
481+
"""
482+
c = Constants()
483+
state = dict(c.__getstate__())
484+
del state['titles']
485+
restored = Constants.__new__(Constants)
486+
with pytest.raises(ValueError, match='titles'):
487+
restored.__setstate__(state)
488+
448489

449490
class SuffixesPrefixesTitlesPerformanceTests(HumanNameTestBase):
450491
"""Guard against accidental cache removal on suffixes_prefixes_titles.

0 commit comments

Comments
 (0)