Skip to content

Commit

Permalink
Fix ordering inside searchindex.js not being deterministic
Browse files Browse the repository at this point in the history
  • Loading branch information
pietroalbini committed Sep 14, 2023
1 parent f0c25a0 commit c79c50d
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGES.rst
Expand Up @@ -18,6 +18,7 @@ Bugs fixed

* #11668: Raise a useful error when ``theme.conf`` is missing.
Patch by Vinay Sajip.
* #11622: Fix ordering inside searchindex.js not being deterministic.

Testing
-------
Expand Down
2 changes: 1 addition & 1 deletion sphinx/search/__init__.py
Expand Up @@ -162,7 +162,7 @@ class _JavaScriptIndex:
SUFFIX = ')'

def dumps(self, data: Any) -> str:
return self.PREFIX + json.dumps(data) + self.SUFFIX
return self.PREFIX + json.dumps(data, sort_keys=True) + self.SUFFIX

def loads(self, s: str) -> Any:
data = s[len(self.PREFIX):-len(self.SUFFIX)]
Expand Down
20 changes: 20 additions & 0 deletions tests/test_search.py
Expand Up @@ -304,3 +304,23 @@ def test_parallel(app):
app.build()
index = load_searchindex(app.outdir / 'searchindex.js')
assert index['docnames'] == ['index', 'nosearch', 'tocitem']


@pytest.mark.sphinx(testroot='search')
def test_search_index_is_deterministic(app):
app.builder.build_all()
index = load_searchindex(app.outdir / 'searchindex.js')

def check_if_dicts_are_sorted(item):
if isinstance(item, dict):
assert list(item.keys()) == sorted(item.keys())
for child in item.values():
check_if_dicts_are_sorted(child)
# Lists in the search index cannot be sorted: for some lists, their
# position inside the list is referenced elsewhere in the index, so if
# we were to sort lists, the search index would break.
elif isinstance(item, list):
for child in item:
check_if_dicts_are_sorted(child)

check_if_dicts_are_sorted(index)

0 comments on commit c79c50d

Please sign in to comment.