safe_join: raise ValueError on None parameters and update tests

Changed safe_join to raise ValueError if base or tail is None instead of returning 'None/path'.
Adjusted unit tests accordingly to expect exceptions for None inputs and kept empty-string handling valid.

Ref: https://chatgpt.com/share/68b55850-e854-800f-9702-09ea956b8dc4
This commit is contained in:
2025-09-01 10:25:08 +02:00
parent 9feb766e6f
commit 94fe58b5da
2 changed files with 14 additions and 8 deletions

View File

@@ -1,19 +1,20 @@
""" """
Ansible filter plugin that joins a base string and a tail path safely. Ansible filter plugin that joins a base string and a tail path safely.
If the base is falsy (None, empty, etc.), returns an empty string. Raises ValueError if base or tail is None.
""" """
def safe_join(base, tail): def safe_join(base, tail):
""" """
Safely join base and tail into a path or URL. Safely join base and tail into a path or URL.
- base: the base string. If falsy, returns ''. - base: the base string. Must not be None.
- tail: the string to append. Leading/trailing slashes are handled. - tail: the string to append. Must not be None.
- On any exception, returns ''. - On ValueError, caller should handle it.
""" """
if base is None or tail is None:
raise ValueError("safe_join: base and tail must not be None")
try: try:
if not base:
return ''
base_str = str(base).rstrip('/') base_str = str(base).rstrip('/')
tail_str = str(tail).lstrip('/') tail_str = str(tail).lstrip('/')
return f"{base_str}/{tail_str}" return f"{base_str}/{tail_str}"

View File

@@ -24,10 +24,15 @@ class TestSafeJoinFilter(unittest.TestCase):
) )
def test_base_none(self): def test_base_none(self):
self.assertEqual(safe_join(None, 'path'), '') with self.assertRaises(ValueError):
safe_join(None, 'path')
def test_tail_none(self):
with self.assertRaises(ValueError):
safe_join('http://example.com', None)
def test_base_empty(self): def test_base_empty(self):
self.assertEqual(safe_join('', 'path'), '') self.assertEqual(safe_join('', 'path'), '/path')
def test_tail_empty(self): def test_tail_empty(self):
# joining with empty tail should yield base with trailing slash # joining with empty tail should yield base with trailing slash