Skip to content

Commit b49233c

Browse files
committed
Handle non-mapping in metadata
1 parent f5e94f8 commit b49233c

2 files changed

Lines changed: 106 additions & 0 deletions

File tree

dfetch/project/metadata.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ def from_file(cls, path: str) -> "Metadata":
9999
except (KeyError, TypeError) as exc:
100100
raise InvalidMetadataError(str(exc)) from exc
101101

102+
if not isinstance(data, dict):
103+
raise InvalidMetadataError(
104+
f"Expected a mapping under 'dfetch', got {type(data).__name__}"
105+
)
102106
return cls(data)
103107

104108
def fetched(

tests/test_metadata.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
"""Test metadata loading."""
2+
3+
# mypy: ignore-errors
4+
# flake8: noqa
5+
6+
import textwrap
7+
8+
import pytest
9+
10+
from dfetch.project.metadata import InvalidMetadataError, Metadata
11+
12+
VALID_METADATA = """\
13+
dfetch:
14+
remote_url: https://example.com/repo
15+
branch: main
16+
tag: ''
17+
revision: abc123
18+
last_fetch: 01/01/2000, 00:00:00
19+
hash: deadbeef
20+
patch: ''
21+
"""
22+
23+
24+
def _write_metadata(tmp_path, content):
25+
path = tmp_path / ".dfetch_data.yaml"
26+
path.write_text(textwrap.dedent(content))
27+
return str(path)
28+
29+
30+
def test_from_file_raises_when_dfetch_value_is_a_scalar(tmp_path):
31+
"""A scalar under 'dfetch:' must raise InvalidMetadataError, not AttributeError."""
32+
path = _write_metadata(tmp_path, "dfetch: just-a-string\n")
33+
with pytest.raises(InvalidMetadataError):
34+
Metadata.from_file(path)
35+
36+
37+
def test_from_file_raises_when_dfetch_value_is_a_list(tmp_path):
38+
"""A list under 'dfetch:' must raise InvalidMetadataError, not AttributeError."""
39+
path = _write_metadata(tmp_path, "dfetch:\n - item1\n - item2\n")
40+
with pytest.raises(InvalidMetadataError):
41+
Metadata.from_file(path)
42+
43+
44+
def test_from_file_raises_when_dfetch_value_is_null(tmp_path):
45+
"""A null under 'dfetch:' must raise InvalidMetadataError, not AttributeError."""
46+
path = _write_metadata(tmp_path, "dfetch:\n")
47+
with pytest.raises(InvalidMetadataError):
48+
Metadata.from_file(path)
49+
50+
51+
def test_from_file_raises_on_invalid_yaml_syntax(tmp_path):
52+
"""Broken YAML syntax must raise InvalidMetadataError."""
53+
path = _write_metadata(tmp_path, "dfetch: [unclosed bracket\n")
54+
with pytest.raises(InvalidMetadataError):
55+
Metadata.from_file(path)
56+
57+
58+
def test_from_file_raises_when_dfetch_key_is_absent(tmp_path):
59+
"""A file with no 'dfetch' top-level key must raise InvalidMetadataError."""
60+
path = _write_metadata(tmp_path, "other_key: value\n")
61+
with pytest.raises(InvalidMetadataError):
62+
Metadata.from_file(path)
63+
64+
65+
def test_from_file_loads_remote_url(tmp_path):
66+
"""remote_url is read back correctly from a valid file."""
67+
path = _write_metadata(tmp_path, VALID_METADATA)
68+
meta = Metadata.from_file(path)
69+
assert meta.remote_url == "https://example.com/repo"
70+
71+
72+
def test_from_file_loads_branch(tmp_path):
73+
"""branch is read back correctly from a valid file."""
74+
path = _write_metadata(tmp_path, VALID_METADATA)
75+
meta = Metadata.from_file(path)
76+
assert meta.branch == "main"
77+
78+
79+
def test_from_file_loads_revision(tmp_path):
80+
"""revision is read back correctly from a valid file."""
81+
path = _write_metadata(tmp_path, VALID_METADATA)
82+
meta = Metadata.from_file(path)
83+
assert meta.revision == "abc123"
84+
85+
86+
def test_from_file_loads_hash(tmp_path):
87+
"""hash is read back correctly from a valid file."""
88+
path = _write_metadata(tmp_path, VALID_METADATA)
89+
meta = Metadata.from_file(path)
90+
assert meta.hash == "deadbeef"
91+
92+
93+
def test_from_file_uses_defaults_for_missing_fields(tmp_path):
94+
"""A minimal mapping with only the 'dfetch' key and no fields uses defaults."""
95+
path = _write_metadata(tmp_path, "dfetch: {}\n")
96+
meta = Metadata.from_file(path)
97+
assert meta.remote_url == ""
98+
assert meta.branch == ""
99+
assert meta.revision == ""
100+
assert meta.hash == ""
101+
assert meta.patch == []
102+
assert meta.dependencies == []

0 commit comments

Comments
 (0)