Skip to content

Commit ae596fc

Browse files
committed
fix: propagate variant needs for refs with fragments
1 parent b861ee4 commit ae596fc

2 files changed

Lines changed: 90 additions & 2 deletions

File tree

preprocess_schemas.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -597,8 +597,9 @@ def extract_external_refs(schema, path):
597597
for node in iter_nodes(data):
598598
if isinstance(node, dict) and "$ref" in node:
599599
ref = node["$ref"]
600-
if "#" not in ref:
601-
abs_path = str((path.parent / ref).resolve())
600+
ref_file, _, _ = ref.partition("#")
601+
if ref_file:
602+
abs_path = str((path.parent / ref_file).resolve())
602603
refs.append((name, abs_path))
603604
return refs
604605

tests/test_codegen_pipeline.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,93 @@ def test_main_preprocesses_schema_tree_end_to_end(self) -> None:
591591
self.assertEqual(set(parent_variant["required"]), {"id", "child"})
592592
self.assertEqual(child_variant["required"], ["value"])
593593

594+
def test_propagation_with_fragment(self) -> None:
595+
"""Propagation should work even if the reference has a fragment."""
596+
with tempfile.TemporaryDirectory() as temp_dir:
597+
root = Path(temp_dir)
598+
preprocess_schemas.save_json(
599+
{
600+
"$defs": {
601+
"entity": {
602+
"type": "object",
603+
"properties": {"id": {"type": "string"}},
604+
"required": ["id"],
605+
}
606+
}
607+
},
608+
root / "ucp.json",
609+
)
610+
preprocess_schemas.save_json(
611+
{
612+
"$id": "https://ucp.dev/schemas/child.json",
613+
"title": "Child",
614+
"type": "object",
615+
"$defs": {
616+
"item": {
617+
"type": "object",
618+
"properties": {
619+
"grandchild": {
620+
"$ref": "grandchild.json"
621+
}
622+
}
623+
}
624+
},
625+
"properties": {
626+
"dummy": {"type": "string"}
627+
}
628+
},
629+
root / "child.json",
630+
)
631+
preprocess_schemas.save_json(
632+
{
633+
"$id": "https://ucp.dev/schemas/grandchild.json",
634+
"title": "Grandchild",
635+
"type": "object",
636+
"properties": {
637+
"value": {
638+
"type": "string",
639+
"ucp_request": {"create": "required"},
640+
}
641+
},
642+
},
643+
root / "grandchild.json",
644+
)
645+
preprocess_schemas.save_json(
646+
{
647+
"$id": "https://ucp.dev/schemas/parent.json",
648+
"title": "Parent",
649+
"allOf": [{"$ref": "ucp.json#/$defs/entity"}],
650+
"properties": {
651+
"child_item": {
652+
"$ref": "child.json#/$defs/item",
653+
"ucp_request": {"create": "required"},
654+
}
655+
},
656+
},
657+
root / "parent.json",
658+
)
659+
660+
with (
661+
mock.patch.object(
662+
sys,
663+
"argv",
664+
["preprocess_schemas.py", str(root)],
665+
),
666+
contextlib.redirect_stdout(io.StringIO()),
667+
):
668+
preprocess_schemas.main()
669+
670+
self.assertTrue((root / "child_create_request.json").exists(), "child_create_request.json was not generated")
671+
self.assertTrue((root / "grandchild_create_request.json").exists(), "grandchild_create_request.json was not generated")
672+
673+
parent_variant = preprocess_schemas.load_json(
674+
root / "parent_create_request.json"
675+
)
676+
self.assertEqual(
677+
parent_variant["properties"]["child_item"]["$ref"],
678+
"child_create_request.json#/$defs/item",
679+
)
680+
594681

595682
class MetadataUnionTest(unittest.TestCase):
596683
"""The UcpMetadata root union is derived from ucp.json $defs."""

0 commit comments

Comments
 (0)