Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions sphinx_needs/external_needs.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,17 @@ def load_external_needs(
data = needs_json["versions"][version]
needs = data["needs"]
except KeyError:
uri = source.get("json_url", source.get("json_path", "unknown"))
raise NeedsExternalException(
clean_log(
f"Version {version} not found in json file from {uri}: {list(needs_json.get('versions'))}"
if not needs_json.get("versions"):
# The versions dict is empty, so no needs were ever added.
data = {}
needs = {}
else:
uri = source.get("json_url", source.get("json_path", "unknown"))
raise NeedsExternalException(
clean_log(
f"Version {version} not found in json file from {uri}: {list(needs_json.get('versions'))}"
)
)
)

log.debug(f"Loading {len(needs)} needs.")

Expand Down
1 change: 1 addition & 0 deletions sphinx_needs/needsfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ def wipe_version(self, version: str) -> None:
del self.needs_list["versions"][version]

def _finalise(self) -> None:
self.update_or_add_version(self.current_version)
# We need to rewrite some data, because this kind of data gets overwritten during needs.json import
if not self.needs_config.reproducible_json:
self.needs_list["created"] = datetime.now().isoformat()
Expand Down
6 changes: 6 additions & 0 deletions tests/__snapshots__/test_needimport.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -2116,6 +2116,12 @@
dict({
'current_version': '1.0',
'versions': dict({
'1.0': dict({
'needs': dict({
}),
'needs_amount': 0,
'needs_defaults_removed': True,
}),
}),
})
# ---
Expand Down
3 changes: 3 additions & 0 deletions tests/doc_test/doc_needs_builder_empty/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
project = "doc_needs_builder_empty"

extensions = ["sphinx_needs"]
4 changes: 4 additions & 0 deletions tests/doc_test/doc_needs_builder_empty/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Empty doc
=========

There are no needs here.
49 changes: 49 additions & 0 deletions tests/test_external.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,52 @@ def test_external_allow_type_coercion_false(test_app):
assert strip_colors(app._warning.getvalue()).splitlines() == [
"WARNING: External need 'TEST_01' in 'needs.json' could not be added: 'tags' value is invalid: Invalid value for field 'tags': 'a,b,c' [needs.load_external_need]"
]


@pytest.mark.parametrize(
"test_app",
[
{
"buildername": "html",
"files": [
("index.rst", "Test\n====\n"),
(
"conf.py",
"""
extensions = ["sphinx_needs"]
needs_external_needs = [{
'json_path': 'needs.json',
'base_url': 'http://my_company.com/docs/v1/',
}]
needs_build_json = True
""",
),
],
"no_plantuml": True,
}
],
indirect=True,
)
def test_external_empty_versions(test_app):
"""Test external needs when the loaded needs.json has an empty versions dict."""
json_path = Path(test_app.srcdir) / "needs.json"
json_path.write_text(
json.dumps(
{
"current_version": "0.1.0",
"project": "foo",
"project_url": "https://bar",
"versions": {},
}
)
)

app = test_app
app.build()
assert app.statuscode == 0
assert not app._warning.getvalue()

needs_json = Path(test_app.outdir, "needs.json").read_text()
needs = json.loads(needs_json)
# the empty external needs should just be ignored without crashing.
assert "TEST_01" not in needs["versions"][""]["needs"]
20 changes: 20 additions & 0 deletions tests/test_needs_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,23 @@ def test_needs_html_and_json(test_app):
need_data_1 = needs_1["versions"]["1.0"]["needs"]
need_data_2 = needs_2["versions"]["1.0"]["needs"]
assert need_data_1 == need_data_2


@pytest.mark.parametrize(
"test_app",
[{"buildername": "needs", "srcdir": "doc_test/doc_needs_builder_empty"}],
indirect=True,
)
def test_doc_needs_builder_empty(test_app):
app = test_app
app.build()

needs_list = json.loads(Path(app.outdir, "needs.json").read_text())
assert "current_version" in needs_list
assert needs_list["current_version"] == ""

version = needs_list["current_version"]
assert "versions" in needs_list
assert version in needs_list["versions"]
assert needs_list["versions"][version]["needs_amount"] == 0
assert needs_list["versions"][version]["needs"] == {}