Skip to content

Commit 55e500e

Browse files
committed
fix: follow properties and items when collecting category templates (#220)
- walk properties and items after allOf, definitions and $defs - a referenced schema is walked at its first occurrence only - update the docstring
1 parent 9f606f4 commit 55e500e

2 files changed

Lines changed: 60 additions & 4 deletions

File tree

‎src/osw/core.py‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,13 +259,15 @@ def collect_category_template_titles(
259259
260260
Mirrors the editor: the schema of the meta categories is bundled, the uuid of
261261
every schema is collected after the schemas below it (allOf, oneOf, anyOf,
262-
definitions and $defs are followed in this order, so the most generic schema
263-
comes first) and the result starts with Category:Category.
262+
definitions, $defs, every entry of properties and the items of each property
263+
are followed in this order, so the most generic schema comes first) and the
264+
result starts with Category:Category. A referenced schema is followed only
265+
at its first occurrence, like in a bundled schema.
264266
Category:Category and Category:Entity are not collected. Follows
265267
osl.util.postProcessPage (PageBot.js) with editor.jsonschema.subschemas_uuids
266268
(MwJson_schema.js, _preprocess) in mediawiki-extensions-OpenSemanticLab and
267-
mediawiki-extensions-MwJson. Schemas reached through properties are not
268-
followed.
269+
mediawiki-extensions-MwJson. Only references to category pages are
270+
followed, a reference to another page, e.g. JsonSchema:Label, is not.
269271
270272
Parameters
271273
----------
@@ -310,6 +312,11 @@ def walk(schema: Any) -> None:
310312
if isinstance(schema.get(key), dict):
311313
for entry in schema[key].values():
312314
walk(entry)
315+
if isinstance(schema.get("properties"), dict):
316+
for entry in schema["properties"].values():
317+
walk(entry)
318+
if isinstance(entry, dict):
319+
walk(entry.get("items"))
313320
uuid = schema.get("uuid")
314321
if uuid and uuid not in (CATEGORY_CATEGORY_UUID, CATEGORY_ENTITY_UUID):
315322
title = "Category:" + get_osw_id(uuid)

‎tests/test_store_entity_category_templates.py‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,52 @@ def get_slot_content(self, slot):
202202

203203
assert titles == ["Category:Category"]
204204
assert "No jsonschema found for Category:Category" in caplog.text
205+
206+
207+
def test_collect_follows_properties_and_items_in_wiki_order():
208+
meta = "Category:OSW0a1b2c3d4e5f4a6b8c7d9e0f1a2b3c4d"
209+
prop_cat = "Category:OSW11111111222243338444555555555555"
210+
items_cat = "Category:OSW66666666777748889999aaaaaaaaaaaa"
211+
212+
def ref(title):
213+
return {"$ref": f"/wiki/{title}?action=raw&slot=jsonschema"}
214+
215+
schemas = {
216+
meta: {
217+
"uuid": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
218+
"allOf": [ref(CHARACTERISTIC_TYPE)],
219+
"properties": {
220+
"first": ref(prop_cat),
221+
"list": {"type": "array", "items": ref(items_cat)},
222+
# the second reference to a bundled schema is not walked again
223+
"again": ref(prop_cat),
224+
},
225+
},
226+
CHARACTERISTIC_TYPE: {"uuid": "ffe74f29-1d35-4037-b318-c422591c5023"},
227+
prop_cat: {"uuid": "11111111-2222-4333-8444-555555555555"},
228+
items_cat: {"uuid": "66666666-7777-4888-9999-aaaaaaaaaaaa"},
229+
}
230+
requested = []
231+
232+
class Page:
233+
def __init__(self, title):
234+
self.title = title
235+
236+
def get_slot_content(self, slot):
237+
return schemas[self.title]
238+
239+
def get_pages(titles):
240+
requested.extend(titles)
241+
return [Page(t) for t in titles]
242+
243+
titles = collect_category_template_titles(get_pages, [meta])
244+
245+
# allOf first, then properties in their order, then the uuid of the node itself
246+
assert titles == [
247+
"Category:Category",
248+
CHARACTERISTIC_TYPE,
249+
prop_cat,
250+
items_cat,
251+
meta,
252+
]
253+
assert requested.count(prop_cat) == 1

0 commit comments

Comments
 (0)