From b44f0fbfbd997360fa3e21ed59555d2d85767022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Walter-=E6=A2=81=E6=96=87=E8=B6=85?= Date: Wed, 5 Aug 2026 17:50:17 +0800 Subject: [PATCH] fix: validate relationship column pair counts --- validation/tests/test_validate.py | 60 +++++++++++++++++++++++++++++++ validation/validate.py | 7 ++++ 2 files changed, 67 insertions(+) create mode 100644 validation/tests/test_validate.py diff --git a/validation/tests/test_validate.py b/validation/tests/test_validate.py new file mode 100644 index 00000000..8e4f23da --- /dev/null +++ b/validation/tests/test_validate.py @@ -0,0 +1,60 @@ +from importlib.util import module_from_spec, spec_from_file_location +from pathlib import Path + + +_VALIDATE_PATH = Path(__file__).parents[1] / "validate.py" +_SPEC = spec_from_file_location("ossie_validate", _VALIDATE_PATH) +assert _SPEC is not None and _SPEC.loader is not None +_VALIDATE = module_from_spec(_SPEC) +_SPEC.loader.exec_module(_VALIDATE) + +validate_references = _VALIDATE.validate_references + + +def _document_with_relationship(from_columns: list[str], to_columns: list[str]) -> dict: + return { + "version": "0.2.0.dev0", + "semantic_model": [ + { + "name": "m", + "datasets": [ + {"name": "orders", "source": "db.s.orders"}, + {"name": "customers", "source": "db.s.customers"}, + ], + "relationships": [ + { + "name": "orders_to_customers", + "from": "orders", + "to": "customers", + "from_columns": from_columns, + "to_columns": to_columns, + } + ], + } + ], + } + + +def test_validate_references_rejects_mismatched_relationship_column_counts() -> None: + errors = validate_references( + _document_with_relationship( + from_columns=["customer_id", "region_id"], + to_columns=["id"], + ) + ) + + assert errors == [ + "[Relationship] Relationship 'orders_to_customers' in model 'm' has " + "2 from_columns but 1 to_columns" + ] + + +def test_validate_references_accepts_matching_relationship_column_counts() -> None: + errors = validate_references( + _document_with_relationship( + from_columns=["customer_id", "region_id"], + to_columns=["id", "region_id"], + ) + ) + + assert errors == [] diff --git a/validation/validate.py b/validation/validate.py index 258d34f1..7c7dbe90 100644 --- a/validation/validate.py +++ b/validation/validate.py @@ -140,11 +140,18 @@ def validate_references(data: dict) -> list[str]: rel_name = rel.get("name", "") from_ds = rel.get("from") to_ds = rel.get("to") + from_columns = rel.get("from_columns") or [] + to_columns = rel.get("to_columns") or [] if from_ds and from_ds not in dataset_names: errors.append(f"[Reference] Relationship '{rel_name}' in model '{model_name}' references unknown dataset '{from_ds}'") if to_ds and to_ds not in dataset_names: errors.append(f"[Reference] Relationship '{rel_name}' in model '{model_name}' references unknown dataset '{to_ds}'") + if len(from_columns) != len(to_columns): + errors.append( + f"[Relationship] Relationship '{rel_name}' in model '{model_name}' has " + f"{len(from_columns)} from_columns but {len(to_columns)} to_columns" + ) return errors